{
  "reservations": {
    "1": "foundation-auth",
    "2": "factory-auth",
    "3": "registrar-lifecycle",
    "4": "thing-state-machine",
    "5": "state-changes-feed",
    "6": "subscriptions",
    "7": "identity-blacklist",
    "8": "trust-anchor",
    "9": "internal-cross-domain-reserved"
  },
  "errors": [
    {
      "code": "THM-10100",
      "class": "jwt-expired",
      "status": 401,
      "title": "JWT expired",
      "description": "The bearer token has expired. Obtain a fresh token from the identity provider and retry the request.",
      "type_uri": "https://docs.fgai/thingmake/errors/jwt-expired",
      "since": "phase-10"
    },
    {
      "code": "THM-10110",
      "class": "jwt-invalid-signature",
      "status": 401,
      "title": "JWT signature invalid",
      "description": "The bearer token signature could not be verified. Obtain a freshly signed token and retry.",
      "type_uri": "https://docs.fgai/thingmake/errors/jwt-invalid-signature",
      "since": "phase-10"
    },
    {
      "code": "THM-10120",
      "class": "jwt-missing",
      "status": 401,
      "title": "JWT missing",
      "description": "No bearer token was supplied. Attach an Authorization header carrying a valid bearer token and retry.",
      "type_uri": "https://docs.fgai/thingmake/errors/jwt-missing",
      "since": "phase-10"
    },
    {
      "code": "THM-10130",
      "class": "pdp-unreachable",
      "status": 503,
      "title": "Authorization service unavailable",
      "description": "The authorization decision service is temporarily unreachable. Retry after a short backoff.",
      "type_uri": "https://docs.fgai/thingmake/errors/pdp-unreachable",
      "since": "phase-10"
    },
    {
      "code": "THM-10140",
      "class": "pdp-denied",
      "status": 403,
      "title": "Action denied by policy",
      "description": "The requested action was denied by policy. Confirm the caller has the required entitlement before retrying.",
      "type_uri": "https://docs.fgai/thingmake/errors/pdp-denied",
      "since": "phase-10"
    },
    {
      "code": "THM-10150",
      "class": "validation-failed",
      "status": 400,
      "title": "Request validation failed",
      "description": "The request body or query parameters did not pass schema validation. Inspect the errors array and resubmit.",
      "type_uri": "https://docs.fgai/thingmake/errors/validation-failed",
      "since": "phase-10"
    },
    {
      "code": "THM-10160",
      "class": "internal-error",
      "status": 500,
      "title": "Internal server error",
      "description": "An unexpected internal error occurred. Retry after a backoff; if the error persists contact platform support.",
      "type_uri": "https://docs.fgai/thingmake/errors/internal-error",
      "since": "phase-10"
    },
    {
      "code": "THM-20100",
      "class": "factory-auth-failed",
      "status": 401,
      "title": "Factory authentication failed",
      "description": "Factory authentication did not succeed. Confirm the Authorization: FGAI-HMAC-SHA256 signature, X-FGAI-Date, and X-FGAI-Content-SHA256 headers before retrying.",
      "type_uri": "https://docs.fgai/thingmake/errors/factory-auth-failed",
      "since": "phase-26"
    },
    {
      "code": "THM-20110",
      "class": "factory-auth-missing-header",
      "status": 401,
      "title": "Required FGAI-HMAC-SHA256 signing header missing",
      "description": "A required signing header is missing (Authorization: FGAI-HMAC-SHA256, X-FGAI-Date, or X-FGAI-Content-SHA256). Attach all signing headers and retry.",
      "type_uri": "https://docs.fgai/thingmake/errors/factory-auth-missing-header",
      "since": "phase-26"
    },
    {
      "code": "THM-20120",
      "class": "factory-auth-invalid-signature",
      "status": 401,
      "title": "Factory request signature mismatch",
      "description": "The Signature in the Authorization: FGAI-HMAC-SHA256 header did not match the canonical request derived server-side, or X-FGAI-Content-SHA256 did not match the body hash. Re-compute the signature and retry.",
      "type_uri": "https://docs.fgai/thingmake/errors/factory-auth-invalid-signature",
      "since": "phase-26"
    },
    {
      "code": "THM-20130",
      "class": "factory-auth-expired-timestamp",
      "status": 401,
      "title": "Factory request timestamp outside skew window",
      "description": "The X-FGAI-Date timestamp is outside the accepted skew window. Re-sign with a fresh X-FGAI-Date and retry.",
      "type_uri": "https://docs.fgai/thingmake/errors/factory-auth-expired-timestamp",
      "since": "phase-26"
    },
    {
      "code": "THM-20140",
      "class": "factory-auth-unknown-access-key",
      "status": 401,
      "title": "Access key id not recognised",
      "description": "The access-key id in the Authorization: FGAI-HMAC-SHA256 Credential is not recognised. Confirm the access-key id is current and bound to an active factory service.",
      "type_uri": "https://docs.fgai/thingmake/errors/factory-auth-unknown-access-key",
      "since": "phase-26"
    },
    {
      "code": "THM-20150",
      "class": "factory-auth-replay",
      "status": 401,
      "title": "Factory request replay detected",
      "description": "A replay of an earlier signed request was detected (a duplicate Authorization Signature within the skew window). Re-sign the request with a fresh X-FGAI-Date.",
      "type_uri": "https://docs.fgai/thingmake/errors/factory-auth-replay",
      "since": "phase-26"
    },
    {
      "code": "THM-20160",
      "class": "factory-drain-blocked",
      "status": 409,
      "title": "Cannot drain factory_service: active saga legs still reference this row",
      "description": "The factory service cannot be drained while active saga legs reference it. Wait for the legs to settle and retry.",
      "type_uri": "https://docs.fgai/thingmake/errors/factory-drain-blocked",
      "since": "phase-30"
    },
    {
      "code": "THM-20170",
      "class": "factory-provisioning-failed",
      "status": 502,
      "title": "Factory credential provisioning via DotID failed",
      "description": "Provisioning the factory's DotID service-user or access-key failed upstream; no factory service was registered. Retry after a backoff, or confirm the DotID provisioning surface is reachable.",
      "type_uri": "https://docs.fgai/thingmake/errors/factory-provisioning-failed",
      "since": "phase-42"
    },
    {
      "code": "THM-20180",
      "class": "factory-provisioning-account-not-found",
      "status": 404,
      "title": "Owning account for the registrar could not be resolved",
      "description": "The registrar has no resolvable owning account to provision the factory service-user under. Confirm the registrar exists and carries a valid account_id before retrying.",
      "type_uri": "https://docs.fgai/thingmake/errors/factory-provisioning-account-not-found",
      "since": "phase-42"
    },
    {
      "code": "THM-20190",
      "class": "factory-provisioning-forbidden",
      "status": 403,
      "title": "Caller is not authorized to register a factory for this registrar's account",
      "description": "The authenticated caller's account does not own the supplied registrar. Register the factory service under a registrar in your own account, or use a principal that owns the target registrar.",
      "type_uri": "https://docs.fgai/thingmake/errors/factory-provisioning-forbidden",
      "since": "phase-42"
    },
    {
      "code": "THM-30100",
      "class": "registrar-not-found",
      "status": 404,
      "title": "Registrar not found",
      "description": "Registrar with the given id does not exist or is no longer accessible to this caller.",
      "type_uri": "https://docs.fgai/thingmake/errors/registrar-not-found",
      "since": "phase-10"
    },
    {
      "code": "THM-30110",
      "class": "registrar-already-decided",
      "status": 409,
      "title": "Registrar already approved or rejected",
      "description": "Registrar approval is final. Inspect the current registrar status and adjust the workflow instead of re-deciding.",
      "type_uri": "https://docs.fgai/thingmake/errors/registrar-already-decided",
      "since": "phase-10"
    },
    {
      "code": "THM-30120",
      "class": "provisioning-run-not-found",
      "status": 404,
      "title": "Provisioning run not found",
      "description": "The provisioning run id is unknown or has been pruned. Confirm the run id from the registrar audit trail.",
      "type_uri": "https://docs.fgai/thingmake/errors/provisioning-run-not-found",
      "since": "phase-10"
    },
    {
      "code": "THM-30130",
      "class": "access-request-not-found",
      "status": 404,
      "title": "Access request not found",
      "description": "The access-request id is unknown or no longer accessible. Confirm the id from the originating notification.",
      "type_uri": "https://docs.fgai/thingmake/errors/access-request-not-found",
      "since": "phase-10"
    },
    {
      "code": "THM-30140",
      "class": "access-request-already-decided",
      "status": 409,
      "title": "Access request already decided",
      "description": "Access-request decisions are final. Inspect the recorded decision rather than re-submitting one.",
      "type_uri": "https://docs.fgai/thingmake/errors/access-request-already-decided",
      "since": "phase-10"
    },
    {
      "code": "THM-30150",
      "class": "enrollment-not-found",
      "status": 404,
      "title": "Enrollment not found",
      "description": "No enrollment matches the supplied id. Confirm the enrollment id from the recent provisioning run.",
      "type_uri": "https://docs.fgai/thingmake/errors/enrollment-not-found",
      "since": "phase-10"
    },
    {
      "code": "THM-30160",
      "class": "enrollment-deferred-to-phase-11",
      "status": 501,
      "title": "Enrollment lifecycle deferred to Phase 11 Repository carve-out",
      "description": "The enrollment lifecycle surface is not yet generally available; retry once the Repository carve-out ships.",
      "type_uri": "https://docs.fgai/thingmake/errors/enrollment-deferred-to-phase-11",
      "since": "phase-10"
    },
    {
      "code": "THM-40100",
      "class": "thing-not-found",
      "status": 404,
      "title": "Thing not found",
      "description": "No thing matches the supplied id, or the thing is not accessible to the authenticated registrar.",
      "type_uri": "https://docs.fgai/thingmake/errors/thing-not-found",
      "since": "phase-24"
    },
    {
      "code": "THM-40110",
      "class": "thing-invalid-state-transition",
      "status": 409,
      "title": "Thing cannot transition from its current state via this verb",
      "description": "The requested verb is not valid from the thing's current state. Re-read the thing state and choose a legal transition.",
      "type_uri": "https://docs.fgai/thingmake/errors/thing-invalid-state-transition",
      "since": "phase-24"
    },
    {
      "code": "THM-40120",
      "class": "idempotency-key-required",
      "status": 400,
      "title": "Idempotency-Key header is required on governance routes",
      "description": "Governance verbs require an Idempotency-Key header. Attach a stable client-generated key and resubmit.",
      "type_uri": "https://docs.fgai/thingmake/errors/idempotency-key-required",
      "since": "phase-24"
    },
    {
      "code": "THM-40130",
      "class": "idempotency-key-mismatch",
      "status": 422,
      "title": "Idempotency-Key replayed with different request body",
      "description": "The supplied Idempotency-Key was previously used with a different request body. Use a fresh key for distinct payloads.",
      "type_uri": "https://docs.fgai/thingmake/errors/idempotency-key-mismatch",
      "since": "phase-24"
    },
    {
      "code": "THM-40140",
      "class": "annihilate-same-principal",
      "status": 403,
      "title": "ANNIHILATE confirmation must come from a distinct principal",
      "description": "ANNIHILATE requires dual-control. The confirming caller must be a distinct principal from the initiator.",
      "type_uri": "https://docs.fgai/thingmake/errors/annihilate-same-principal",
      "since": "phase-24"
    },
    {
      "code": "THM-40150",
      "class": "saga-not-found",
      "status": 404,
      "title": "Saga not found",
      "description": "No saga matches the supplied id. Confirm the saga id from the originating state-change response.",
      "type_uri": "https://docs.fgai/thingmake/errors/saga-not-found",
      "since": "phase-24"
    },
    {
      "code": "THM-40160",
      "class": "factory-service-not-registered",
      "status": 503,
      "title": "No active factory service registered for the requested role",
      "description": "No active factory service is registered for the role required by this verb. Register or activate a factory service and retry.",
      "type_uri": "https://docs.fgai/thingmake/errors/factory-service-not-registered",
      "since": "phase-24"
    },
    {
      "code": "THM-40170",
      "class": "factory-service-not-found",
      "status": 404,
      "title": "Factory service not found",
      "description": "The factory service id is unknown or no longer visible to this registrar. Confirm the id from the recent inventory list.",
      "type_uri": "https://docs.fgai/thingmake/errors/factory-service-not-found",
      "since": "phase-25"
    },
    {
      "code": "THM-40180",
      "class": "not-found",
      "status": 404,
      "title": "Resource not found",
      "description": "The requested resource does not exist or is no longer accessible to this caller.",
      "type_uri": "https://docs.fgai/thingmake/errors/not-found",
      "since": "phase-25"
    },
    {
      "code": "THM-50100",
      "class": "state-query-registrar-id-rejected",
      "status": 400,
      "title": "?registrar_id= query parameter is rejected; registrar is derived from authenticated identity",
      "description": "The ?registrar_id= query parameter is not accepted on this surface. The registrar is derived from the authenticated identity; drop the parameter and retry.",
      "type_uri": "https://docs.fgai/thingmake/errors/state-query-registrar-id-rejected",
      "since": "phase-27"
    },
    {
      "code": "THM-50110",
      "class": "state-changes-cursor-invalid",
      "status": 400,
      "title": "state-changes cursor malformed or unreadable",
      "description": "The supplied state-changes cursor is malformed. Resume from a previously emitted next_cursor value, or restart without a cursor.",
      "type_uri": "https://docs.fgai/thingmake/errors/state-changes-cursor-invalid",
      "since": "phase-27"
    },
    {
      "code": "THM-50120",
      "class": "state-changes-cursor-expired",
      "status": 410,
      "title": "state-changes cursor older than 72h; full-sync required",
      "description": "The state-changes cursor is older than the retention window. Perform a full sync via GET /api/v1/things and resume polling.",
      "type_uri": "https://docs.fgai/thingmake/errors/state-changes-cursor-expired",
      "since": "phase-27"
    },
    {
      "code": "THM-60100",
      "class": "subscription-not-found",
      "status": 404,
      "title": "webhook subscription not found",
      "description": "No webhook subscription matches the supplied id. Confirm the subscription id from the registrar inventory.",
      "type_uri": "https://docs.fgai/thingmake/errors/subscription-not-found",
      "since": "phase-28"
    },
    {
      "code": "THM-60110",
      "class": "subscription-polling-acknowledgment-required",
      "status": 422,
      "title": "subscribing does not replace the mandatory GET /state-changes polling contract; set acknowledge_polling_still_mandatory=true to proceed",
      "description": "Webhook subscriptions do not replace the mandatory state-changes polling contract. Acknowledge the polling requirement and resubmit.",
      "type_uri": "https://docs.fgai/thingmake/errors/subscription-polling-acknowledgment-required",
      "since": "phase-28"
    },
    {
      "code": "THM-60120",
      "class": "subscription-target-url-invalid",
      "status": 400,
      "title": "target_url must use https://",
      "description": "The subscription target_url must be an https URL. Replace the target_url with a valid https endpoint and retry.",
      "type_uri": "https://docs.fgai/thingmake/errors/subscription-target-url-invalid",
      "since": "phase-28"
    },
    {
      "code": "THM-60130",
      "class": "subscription-state-invalid",
      "status": 409,
      "title": "subscription status transition not permitted",
      "description": "The requested subscription status transition is not permitted from the current state. Re-read the subscription status and choose a legal transition.",
      "type_uri": "https://docs.fgai/thingmake/errors/subscription-state-invalid",
      "since": "phase-28"
    },
    {
      "code": "THM-60140",
      "class": "subscription-event-filter-invalid",
      "status": 400,
      "title": "event_filter must contain only optional new_states + thing_ids string arrays",
      "description": "The event_filter object accepts only new_states and thing_ids string arrays. Remove unknown fields and resubmit.",
      "type_uri": "https://docs.fgai/thingmake/errors/subscription-event-filter-invalid",
      "since": "phase-28"
    },
    {
      "code": "THM-60150",
      "class": "subscription-suspended-cannot-modify",
      "status": 409,
      "title": "SUSPENDED subscription cannot be modified except to PATCH status=ACTIVE",
      "description": "A SUSPENDED subscription cannot be modified. Reactivate the subscription by PATCHing status to ACTIVE, then retry the modification.",
      "type_uri": "https://docs.fgai/thingmake/errors/subscription-suspended-cannot-modify",
      "since": "phase-28"
    },
    {
      "code": "THM-70100",
      "class": "identity-blacklist-not-found",
      "status": 404,
      "title": "Identity not found in blacklist",
      "description": "The supplied identity is not on the blacklist. Confirm the identity value before retrying.",
      "type_uri": "https://docs.fgai/thingmake/errors/identity-blacklist-not-found",
      "since": "phase-29"
    },
    {
      "code": "THM-70110",
      "class": "identity-blacklist-cursor-invalid",
      "status": 400,
      "title": "identity blacklist delta cursor malformed",
      "description": "The blacklist delta cursor is malformed. Resume from a previously emitted next_cursor, or full-sync via /identity-blacklist.",
      "type_uri": "https://docs.fgai/thingmake/errors/identity-blacklist-cursor-invalid",
      "since": "phase-29"
    },
    {
      "code": "THM-70120",
      "class": "identity-blacklist-cursor-expired",
      "status": 410,
      "title": "identity blacklist delta cursor older than 72h; full-sync required",
      "description": "The blacklist delta cursor is older than the retention window. Perform a full sync via GET /identity-blacklist and resume from a fresh cursor.",
      "type_uri": "https://docs.fgai/thingmake/errors/identity-blacklist-cursor-expired",
      "since": "phase-29"
    },
    {
      "code": "THM-70130",
      "class": "identity-blacklist-snapshot-not-ready",
      "status": 503,
      "title": "snapshot not yet generated; retry in a few seconds",
      "description": "The blacklist snapshot has not yet been generated. Retry after a short backoff.",
      "type_uri": "https://docs.fgai/thingmake/errors/identity-blacklist-snapshot-not-ready",
      "since": "phase-29"
    },
    {
      "code": "THM-80100",
      "class": "trust-anchor-fetch-failed",
      "status": 503,
      "title": "Trust-anchor fetch failed: thingmint endpoint unreachable, non-2xx, or unreadable",
      "description": "The upstream trust-anchor endpoint is unreachable or returned an error. Retry after a backoff; the leg will be requeued automatically.",
      "type_uri": "https://docs.fgai/thingmake/errors/trust-anchor-fetch-failed",
      "since": "phase-34"
    },
    {
      "code": "THM-80110",
      "class": "trust-anchor-malformed",
      "status": 502,
      "title": "Trust-anchor PEM parsed but unusable (no kid match, expired, or missing required fields)",
      "description": "The upstream trust-anchor response could not be used (no kid match, expired, or missing required fields). Retry after the upstream is repaired.",
      "type_uri": "https://docs.fgai/thingmake/errors/trust-anchor-malformed",
      "since": "phase-34"
    },
    {
      "code": "THM-80120",
      "class": "trust-anchor-rejected",
      "status": 422,
      "title": "Factory backend rejected the provision leg payload containing trust_anchor",
      "description": "The factory backend rejected the provision-leg payload that contained the trust anchor. Confirm the factory backend accepts the current trust-anchor envelope shape.",
      "type_uri": "https://docs.fgai/thingmake/errors/trust-anchor-rejected",
      "since": "phase-34"
    }
  ]
}
