Deregister a jurisdiction
The registrations.deregister operation: POST /api/v1/registrations/{id}/deregister in the REST API and the registrations_deregister tool in the MCP server.
/api/v1/registrations/{id}/deregisterRecords that the entity's registration for a regime has ended (it deregistered with the tax authority). The
registration becomes deregistered: consumer sales there are then treated like monitored for a regime
with a threshold (a new crossing triggers again) or like blocked_b2c for a zero-threshold regime (spec
§10.1). The registration number and proof stay in its history.
Needs registered. Returns the registration.
Compliance tier (spec §41.4): tax managers, owners and admins. If the organization's approval policy lists
this operation, the call answers approval_required and runs once a second person approves it.
At a glance
- REST:
POST /api/v1/registrations/{id}/deregister - MCP tool:
registrations_deregister - Operation ID:
registrations.deregister - Scope: Legal entity
- Permission:
registrations:write - Risk tier:
compliance - Dry run: Supported (send
Ownrecord-Dry-Run: true) - Idempotency:
Idempotency-Keyrequired - Modes: Test and live
- Authentication: API key with the
registrations:writescope - Since: M3
Request
Path parameters
| Field | Type | Description |
|---|---|---|
id | string | The registration (regn_…) or its regime's ID, e.g. EU_OSS_UNION or US_SALES_TAX:TX. |
Body
A JSON object (Content-Type: application/json):
| Field | Type | Required | Description |
|---|---|---|---|
note | string | No | Why, or anything the team should know; kept in the registration's history and the audit log. |
Response
200 OK with a JSON object:
| Field | Type | Description |
|---|---|---|
id | regn_… ID | |
object | "registration" | |
entityId | ent_… ID | |
livemode | boolean | |
regimeId | string | |
regimeName | string or null | |
jurisdictionIds | array of string | |
state | one of not_applicable, monitored, pre_registration, grace, registered, blocked_b2c, deregistered | |
stateReason | one of 18 values, e.g. home_country, below_threshold, zero_threshold (all in the OpenAPI document) | |
stateChangedAt | date-time | |
armed | boolean | |
triggeredAt | date-time or null | |
deadlineAt | date-time or null | |
autoBlockAt | date-time or null | |
applicationSubmittedAt | date-time or null | |
escalationLevel | integer (0 to 3) | |
registrationNumber | string or null | |
effectiveFrom | date-time or null | |
registeredAt | date-time or null | |
prerequisitesDone | boolean | |
prerequisitesProgress | object | |
prerequisitesProgress.done | integer | |
prerequisitesProgress.total | integer | |
threshold | object or null | |
timeZones | array of string | |
createdAt | date-time | |
updatedAt | date-time | |
prerequisites | array of object | |
prerequisites[].code | string | |
prerequisites[].description | string or null | |
prerequisites[].leadTimeDays | integer or null | |
prerequisites[].status | one of todo, in_progress, done | |
prerequisites[].doneAt | date-time or null | |
prerequisites[].notes | string | |
prerequisites[].owner | string or null | |
prerequisites[].attachments | array of object | |
prerequisites[].attachments[].kind | one of file, reference | |
prerequisites[].attachments[].ref | string | |
prerequisites[].attachments[].label | string or null | |
prerequisites[].attachments[].addedAt | date-time | |
prerequisites[].attachments[].addedBy | string | |
prerequisites[].updatedAt | date-time or null | |
prerequisites[].updatedBy | string or null | |
evidenceFiles | array of object | |
evidenceFiles[].kind | one of file, reference | |
evidenceFiles[].ref | string | |
evidenceFiles[].label | string or null | |
evidenceFiles[].addedAt | date-time | |
evidenceFiles[].addedBy | string | |
history | array of object | |
history[].from | one of not_applicable, monitored, pre_registration, grace, registered, blocked_b2c, deregistered or null | |
history[].to | one of not_applicable, monitored, pre_registration, grace, registered, blocked_b2c, deregistered | |
history[].at | date-time | |
history[].by | string | |
history[].reason | one of 18 values, e.g. home_country, below_threshold, zero_threshold (all in the OpenAPI document) | |
history[].note | string or null | |
counters | array of object | |
counters[].windowKey | string | |
counters[].amount | money | |
counters[].transactionCount | integer | |
counters[].lastEventAt | date-time | |
regime | object or null | |
playbooks | array of object | |
playbooks[].key | string | |
playbooks[].kind | one of registration, filing, deregistration, other | |
playbooks[].markdown | string | |
officialLinks | array of object | |
officialLinks[].label | string | |
officialLinks[].url | string | |
actions | object | |
actions.arm | object | |
actions.arm.allowed | boolean | |
actions.arm.code | string or null | |
actions.arm.message | string or null | |
actions.markApplicationSubmitted | object | |
actions.markApplicationSubmitted.allowed | boolean | |
actions.markApplicationSubmitted.code | string or null | |
actions.markApplicationSubmitted.message | string or null | |
actions.markRegistered | object | |
actions.markRegistered.allowed | boolean | |
actions.markRegistered.code | string or null | |
actions.markRegistered.message | string or null | |
actions.deregister | object | |
actions.deregister.allowed | boolean | |
actions.deregister.code | string or null | |
actions.deregister.message | string or null | |
safetyBufferHours | integer | |
knowledgeCommit | string |
Examples
Deregistered after closing UK sales
POST /api/v1/registrations/regn_01m4tx5nj8emwbyf7y9vcf47xm/deregister
Authorization: Bearer or_test_…
Idempotency-Key: 3f1c9a52-7d0e-4b8f-9a61-0c2d5e8b7f14
Content-Type: application/json
{
"note": "Stopped selling to UK consumers"
}
Response (200):
{
"id": "regn_01m4tx5nj8emwbyf7y9vcf47xm",
"object": "registration",
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"livemode": true,
"regimeId": "GB_VAT_NETP",
"regimeName": "United Kingdom, VAT for non-established taxable persons",
"jurisdictionIds": ["GB"],
"state": "deregistered",
"stateReason": "deregistered",
"stateChangedAt": "2026-10-14T09:30:00.000Z",
"armed": false,
"triggeredAt": null,
"deadlineAt": null,
"autoBlockAt": null,
"applicationSubmittedAt": null,
"escalationLevel": 0,
"registrationNumber": "GB123456789",
"effectiveFrom": null,
"registeredAt": null,
"prerequisitesDone": true,
"prerequisitesProgress": {
"done": 0,
"total": 0
},
"threshold": null,
"timeZones": ["Europe/London"],
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-14T09:30:00.000Z",
"prerequisites": [],
"evidenceFiles": [],
"history": [],
"counters": [],
"regime": null,
"playbooks": [],
"officialLinks": [],
"actions": {
"arm": {
"allowed": false,
"code": "registration_transition_invalid",
"message": "EU_OSS_UNION is pre_registration, so \"arm\" isn't possible."
},
"markApplicationSubmitted": {
"allowed": false,
"code": "registration_transition_invalid",
"message": "EU_OSS_UNION is pre_registration, so \"application_submitted\" isn't possible."
},
"markRegistered": {
"allowed": true,
"code": null,
"message": null
},
"deregister": {
"allowed": false,
"code": "registration_transition_invalid",
"message": "EU_OSS_UNION is pre_registration, so \"deregister\" isn't possible."
}
},
"safetyBufferHours": 72,
"knowledgeCommit": "1c14b2ec912aca347dd518b2044096f3b5d8eef1"
}
Errors
| Code | HTTP status | When | What to do |
|---|---|---|---|
registration_transition_invalid | 409 | The registration isn't registered. | Check the registration's state (details.state): details.allowed_from lists the states the action needs. Reload the registration and try the action that fits its state. |
validation_failed | 400 | A field is missing or malformed (details.issues). | Fix the fields listed in details.issues and send the request again. |
resource_not_found | 404 | This entity has no such registration in this mode. | Check the ID and that your credentials are scoped to the right organization, entity, brand and mode. |
jurisdiction_blocked | 422 | The tax knowledge no longer has a usable regime for this registration, so it can't change now. | This jurisdiction isn't covered by usable tax knowledge for this seller. Contact support if you need to sell there. |
approval_required | 202 | The organization's approval policy needs a second person for this action; nothing changed yet. | Nothing ran yet. An approver reviews approval.summary and the dry-run result in the console (approval.approveUrl). Poll GET /approvals/{id} or watch for the approval.resolved event; sending the same request again with the same Idempotency-Key returns the same approval. |
approval_rejected | 409 | The same request was sent again after it was rejected. | Read the reason in details.approval.rejection. To try again, send a new request with a new Idempotency-Key. |
approval_expired | 409 | The same request was sent again after its approval request expired. | Send the request again with a new Idempotency-Key to create a new approval request. Requests expire after 72 hours. |
stale_approval | 409 | The approved request could no longer run as requested. | Check the current state (details.approval.failure says what failed), then send a new request with a new Idempotency-Key. |
idempotency_key_reused | 409 | The idempotency key was used before with another input. | Use a new Idempotency-Key for a different request, or resend the original request unchanged. |
livemode_not_allowed | 403 | You have no live-mode access, so you can't change live registrations. | Use test mode, or credentials for the target's mode. Developers need live access granted by an organization owner or admin. |
scope_required | 400 | The request names no legal entity (an org key without Ownrecord-Entity). | Call the operation with credentials or a target at its level: an organization, a legal entity, a brand or the platform (details.required_scope). |
permission_denied | 403 | You can't change this entity's registrations (tax managers, owners and admins can). | Ask an organization owner or admin for a role or scope that allows this action. |
version_conflict | 409 | The registration changed at the same moment (a sale or the deadline job); reload and retry. | Fetch the object again and retry the change. |
It can also return these common errors: api_version_unsupported, invalid_json, unsupported_media_type, authentication_required, api_key_invalid, idempotency_key_required, idempotency_in_progress, approval_policy_denied, rate_limited, internal_error.