REST API Domains - edmozley/freeitsm GitHub Wiki

๐ŸŒ REST API: Domains

The usage guide for the Domains module of the REST API: the domain register, registry lookups, the security checks and their findings, and each domain's history. Mirrors the interactive documentation at System โ†’ API โ†’ Documentation.

[!NOTE] New to the API? The basics table on REST API: Tickets covers base URL, authentication, the response envelope, error codes, rate limits and PATCH semantics - identical across all modules.

What's distinctive about Domains:

๐Ÿข Company-scoped Lists are filtered to the key's companies; a domain outside them is a 404 on every by-id route. New domains land in company_id (checked against the key) or the key's default company.
๐Ÿ” Auth codes never cross the API Responses carry only auth_code_set; a body containing auth_code is refused with 422. A transfer secret belongs behind the analyst permission and its audit trail.
๐Ÿ”Ž Lookups and checks on demand POST /domains/{id}/lookup asks the registry now; POST /domains/{id}/check re-grades now. Both return the domain with what changed.
๐Ÿ“œ Findings in English GET /domains/{id}/findings returns each finding's title and advice filled in, for a consumer with no language file.

Give a key the Domains permissions (read / create / update / delete) under System โ†’ API.


๐Ÿš€ Quick start

B="https://your-server/api/v1"; K="Authorization: Bearer fitsm_โ€ฆ"

# Everything expiring in the next 60 days, soonest first
curl -s -H "$K" "$B/domains?expiring_within_days=60&sort=expiry_date" | jq '.data[] | {domain_name, expiry_date, days_remaining}'

# Add a domain and fill in the registry details straight away
curl -s -H "$K" -H "Content-Type: application/json" -X POST \
     -d '{"domain_name":"example.com","purpose":"primary","lookup":true}' "$B/domains"

# What is wrong with it, and how to fix it
curl -s -H "$K" "$B/domains/42/findings" | jq '.data[] | select(.level=="fail" or .level=="warn") | {title, advice}'

Endpoints

Method Path Permission What
GET /domains domains.read List / search
POST /domains domains.create Add a domain
GET /domains/{id} domains.read One domain
PATCH /domains/{id} domains.update Change fields
DELETE /domains/{id} domains.delete Delete (with its history)
POST /domains/{id}/lookup domains.update Refresh from the registry
POST /domains/{id}/check domains.update Run the checks now
GET /domains/{id}/findings domains.read The last check's findings
GET /domains/{id}/history domains.read Every change, newest first
GET /domain-statuses domains.read Statuses (alerts_enabled marks the ones that stop reminders)
GET /domain-registrar-accounts domains.read Registrar accounts (company-scoped; no passwords exist to return)

List filters

q, domain_name (tidied like input, so a URL matches), status_id, owner_analyst_id, registrar_supplier_id, registrar_account_id, purpose, tag, expiring_within_days, expired=true, transfer_lock=true|false, grade=D,F, company_id, sort (expiry_date default, domain_name, security_score, ssl_expiry_date, created_at, id; prefix - for descending), page / per_page.

Writes

Only domain_name is required on create. Lookups (status_id, owner_analyst_id, registrar_supplier_id, registrar_account_id, tech_contact_id, tech_analyst_id, contract_id, customer_user_id, customer_supplier_id, customer_contact_id) are validated with a 422 naming the field. customer_user_id is the domain's customer โ€” a user in the domain's own company โ€” and comes back as customer: {id, name, email}.

Customer and technical contact (3.1.0, #162). A domain has one customer โ€” customer_user_id, or customer_supplier_id with an optional customer_contact_id โ€” and one technical contact โ€” tech_contact_id (a supplier contact) or tech_analyst_id. Setting one kind clears the other, so a PATCH need only name the new one; naming both kinds in one request is a 422. A customer_contact_id on its own sets customer_supplier_id to that contact's supplier; a contact from a different supplier than the one you name is a 422. Clearing customer_supplier_id clears its contact too. The responses keep customer and tech_contact exactly as before and add tech_analyst: {id, name}, customer_supplier: {id, name} and customer_contact: {id, name, email} beside them, each null when not set. Before Database Verification has added the columns, the three new fields are accepted and ignored. Dates are YYYY-MM-DD. purpose is one of primary, secondary, redirect, email_only, defensive, parked, campaign; renewal_mode one of auto, manual, do_not_renew, unknown. On PATCH, omit a field to leave it, send "" or null to clear it.

Every write goes through the same service as the screens: the same validation, a history row per changed field (source api), and the domain.created / domain.updated / domain.deleted workflow events.

Errors

HTTP code When
400 invalid_parameter unknown sort or purpose
403 forbidden company_id outside the key's scope
404 not_found no such domain, or outside the key's companies
409 conflict the name is already in the register for that company
422 invalid_field / missing_field bad value, unknown id, empty PATCH - or auth_code in the body
502 lookup_failed the registry did not answer, rate-limited, or has no such registration

See also: Domains ยท Domains developer guide ยท REST API