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