Verify a legal entity's tax ID
The entities.verify operation: POST /api/v1/entities/{id}/verify in the REST API and the entities_verify tool in the MCP server.
/api/v1/entities/{id}/verifyChecks the legal entity's home tax ID with its public register and records the answer:
eu_vatwith VIES (with the entity's own VAT ID as requester, so the answer carries a consultation number),gb_vatwith HMRC andch_vatwith the Swiss UID register;verified: the entity is verified (a brand of it may go live once the rest of the go-live checklist holds);invalid: the register doesn't know the number; the entity stays unverified, with the reason innotes. Fix the tax ID (entities.update) or upload a registry extract (entities.registry_extract.upload);unavailable: the register couldn't answer; nothing changes. Try again later.
Other tax ID types have no register to ask (tax_id_check_not_available): upload a registry extract instead.
In development and CI the fixture registers answer (no real register is called).
Needs entities:tax_ids (tax managers, owners and admins).
At a glance
- REST:
POST /api/v1/entities/{id}/verify - MCP tool:
entities_verify - Operation ID:
entities.verify - Scope: Organization, or one of its legal entities or brands
- Permission:
entities:tax_ids - Risk tier:
write - Dry run: Supported (send
Ownrecord-Dry-Run: true) - Idempotency:
Idempotency-Keyrequired - Modes: Test and live
- Authentication: API key with the
entities:tax_idsscope - Since: M12
Request
Path parameters
| Field | Type | Description |
|---|---|---|
id | ent_… ID |
Body
This operation takes no body.
Response
200 OK with a JSON object:
| Field | Type | Description |
|---|---|---|
entity | object | |
entity.id | ent_… ID | |
entity.object | "legal_entity" | |
entity.orgId | org_… ID | |
entity.slug | string | |
entity.legalName | string | |
entity.tradingName | string or null | |
entity.establishment | object | |
entity.establishment.country | string | |
entity.establishment.subdivision | string or null | |
entity.establishment.address | object | |
entity.establishment.address.line1 | string | |
entity.establishment.address.line2 | string or null | |
entity.establishment.address.city | string | |
entity.establishment.address.postalCode | string or null | |
entity.establishment.address.region | string or null | |
entity.establishment.address.country | string | |
entity.establishment.companyRegistryId | string | |
entity.establishment.euVatEstablished | boolean | |
entity.homeTaxId | object | |
entity.homeTaxId.type | string | |
entity.homeTaxId.value | string | |
entity.verification | object | |
entity.verification.status | one of unverified, pending_review, verified, rejected | |
entity.verification.method | one of vies, hmrc, ch_uid, document | |
entity.verification.checkedAt | date-time or null | |
entity.defaultCurrency | string | |
entity.timezone | string | |
entity.invoiceSettings | object | |
entity.invoiceSettings.numberFormat | string | |
entity.invoiceSettings.sequenceResetYearly | boolean | |
entity.invoiceSettings.language | string | |
entity.invoiceSettings.bilingual | string or null | |
entity.invoiceSettings.footerText | string or null | |
entity.invoiceSettings.bankTransfer | object or null | |
entity.status | one of onboarding, active, suspended, archived | |
entity.createdAt | date-time | |
entity.updatedAt | date-time | |
verification | object | |
verification.status | one of unverified, pending_review, verified, rejected | |
verification.method | one of vies, hmrc, ch_uid, document | |
verification.checkedAt | date-time or null | |
verification.consultationNumber | string or null | |
verification.documentFileId | file_… ID or null | |
verification.notes | string or null | |
check | object | |
check.outcome | one of verified, invalid, unavailable | |
check.method | one of vies, hmrc, ch_uid | |
check.consultationNumber | string or null | |
check.reason | string or null | |
check.simulated | boolean | A fixture or dry-run answer (development and CI), not a register's. |
Examples
VIES confirms the VAT ID
POST /api/v1/entities/ent_01m4tx5nj8emwbyf7y9vcf47x2/verify
Authorization: Bearer or_test_…
Idempotency-Key: 3f1c9a52-7d0e-4b8f-9a61-0c2d5e8b7f14
Response (200):
{
"entity": {
"id": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"object": "legal_entity",
"orgId": "org_01m4tx5nj7ekd958x53w4bntcg",
"slug": "acme-hr",
"legalName": "Acme Digital d.o.o.",
"tradingName": null,
"establishment": {
"country": "HR",
"subdivision": null,
"address": {
"line1": "Ilica 1",
"line2": null,
"city": "Zagreb",
"postalCode": "10000",
"region": null,
"country": "HR"
},
"companyRegistryId": "080000000",
"euVatEstablished": true
},
"homeTaxId": {
"type": "eu_vat",
"value": "HR12345678901"
},
"verification": {
"status": "verified",
"method": "vies",
"checkedAt": "2026-10-26T09:00:00.000Z"
},
"defaultCurrency": "EUR",
"timezone": "Europe/Zagreb",
"invoiceSettings": {
"numberFormat": "{series}-{year}-{seq:06}",
"sequenceResetYearly": true,
"language": "en",
"bilingual": null,
"footerText": null,
"bankTransfer": null
},
"status": "active",
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z"
},
"verification": {
"status": "verified",
"method": "vies",
"checkedAt": "2026-10-26T09:00:00.000Z",
"consultationNumber": "WAPIAAAAZ1b2c3d4",
"documentFileId": null,
"notes": null
},
"check": {
"outcome": "verified",
"method": "vies",
"consultationNumber": "WAPIAAAAZ1b2c3d4",
"reason": null,
"simulated": false
}
}
Errors
| Code | HTTP status | When | What to do |
|---|---|---|---|
tax_id_check_not_available | 400 | The tax ID type has no register, or the number isn't well-formed. | Upload an extract from the company register instead: Ownrecord reviews it and verifies the entity. |
entity_already_verified | 409 | The entity is verified already. | Nothing to do. Change its tax ID to verify it again. |
version_conflict | 409 | The entity changed while its tax ID was being checked; try again. | Fetch the object again and retry the change. |
upstream_timeout | 502 | The register didn't answer in time (reported as unavailable). | Retry the request with the same Idempotency-Key after a short wait. |
resource_not_found | 404 | No such legal entity in your scope. | Check the ID and that your credentials are scoped to the right organization, entity, brand and mode. |
permission_denied | 403 | You can't verify this entity. | Ask an organization owner or admin for a role or scope that allows this action. |
It can also return these common errors: validation_failed, api_version_unsupported, invalid_json, unsupported_media_type, authentication_required, api_key_invalid, idempotency_key_required, idempotency_key_reused, idempotency_in_progress, approval_required, approval_rejected, approval_expired, stale_approval, approval_policy_denied, rate_limited, internal_error.