Skip to content
ApiqDevelopers
API v1.64.0Open console
API referenceidentity

Start device signup

POST/v1/signup/device

Start a device-code sign-up — an agent asks a person to approve a new tenant

A coding agent starts a sign-up for the person whose work e-mail it was given and receives an RFC 8628 section 3.2 shaped answer: a device_code to poll POST /v1/signup/device:token with, and a…Show moreA coding agent starts a sign-up for the person whose work e-mail it was given and receives an RFC 8628 section 3.2 shaped answer: a device_code to poll POST /v1/signup/device:token with, and a user_code the person confirms at verification_uri (the consent page, which reads GET /v1/signup/device/requests/{userCode}). The platform e-mails the person a 6-digit code at the same moment; approving needs it (POST /v1/signup/device:approve), so only the owner of the inbox can create the tenant. user_code is 8 letters of the RFC 8628 section 6.1 base-20 alphabet shown as XXXX-XXXX, single use; the request lives 15 minutes (expires_in 900); poll no faster than interval (5 s). The body takes the sign-up fields of POST /v1/signup/verify (organization, accountType, givenName, familyName, country) and the agent name; agent falls back to the X-Agent header. Nothing is created until the person approves; the tenant then carries origin agent and the agent name (DeviceSignupResult). The start answers 200 whatever the e-mail's domain: whether the domain already has a tenant is decided only once the e-mail is proven, at POST /v1/signup/device:approve (409 CONFLICT details.reason TENANT_EXISTS to the person, nextAction request_invite; the request is REFUSED) and then at the agent's poll (the same 409), and only then is that tenant's Owner notified (signup.tenant_exists). So the anonymous start tells no one which domains have an account, notifies no Owner, and no second tenant is created for a domain (an agent cannot fork a company's account). A free-mail domain is accepted for a sandbox tenant only. On DEV and SANDBOX a harness identity domain (AgentManifest.signup.harnessDomains) is approved without inbox proof and creates a sandbox tenant, limited by the per-domain count below. Not envelope-shaped (see the identity tag). MCP: excluded.

Headers

  • X-AgentstringOptional
    The calling agent, as <name>/<version> (<model>), at most 120 characters, e.g.Show moreThe calling agent, as <name>/<version> (<model>), at most 120 characters, e.g. claude-code/2.4 (claude-fable-5-1). Optional on every key-authenticated route in phase 1. Logged and stamped as the agent of the request's records (Attribution.agent) and of a key minted on it (ApiKeyMetadata.agent); a product string, never personal data. POST /v1/signup/device reads it when the body names no agent.

Request body

  • emailstring · emailRequired
  • organizationstringOptional
  • accountTypestringOptional
    what kind of customer a tenant is. BUSINESS is an organisation (the signup before 1.47.0); INDIVIDUAL is one person with no company, whose tenant is named after the person, who verifies with an…Show morewhat kind of customer a tenant is. BUSINESS is an organisation (the signup before 1.47.0); INDIVIDUAL is one person with no company, whose tenant is named after the person, who verifies with an identity check (POST /v1/activation/identity-checks) instead of a business verification and who pays each booking by card through the payment provider's hosted checkout. A tenant created before 1.47.0 reads as BUSINESS. An x-extensible-enum: in a response a client renders the values it knows and treats an unknown one as BUSINESS; in a request a value the server does not know is 400 VALIDATION with details.field accountType.
  • givenNamestringOptional
  • familyNamestringOptional
  • countrystringOptional
  • agentstringOptional

Responses

  • 200The codes (RFC 8628 section 3.2 shape); the person approves at verification_uriDeviceSignupStart
  • 400VALIDATION or UNKNOWN_DOMAINApiErrorResponse
  • 405
    VALIDATION — the public edge serves GET, POST, PUT, PATCH and DELETE only; any other method is refused before the platform sees it (details.reason METHOD_NOT_ALLOWED, details.source edge).Show moreVALIDATION — the public edge serves GET, POST, PUT, PATCH and DELETE only; any other method is refused before the platform sees it (details.reason METHOD_NOT_ALLOWED, details.source edge). Not retryable as sent.
    ApiErrorResponse
  • 413
    VALIDATION — the request body is larger than the surface's limit.Show moreVALIDATION — the request body is larger than the surface's limit. Not retryable as sent: shrink the body. Declared on every operation that takes a request body. details carries exactly one key, maxBodyBytes (integer): the limit that applies to this surface, in bytes.
    ApiErrorResponse
  • 414
    VALIDATION — the request URI (path and query string) is longer than 8 KiB; the public edge refuses it before the platform sees it (details.reason URI_TOO_LONG, details.source edge).Show moreVALIDATION — the request URI (path and query string) is longer than 8 KiB; the public edge refuses it before the platform sees it (details.reason URI_TOO_LONG, details.source edge). Not retryable as sent: send long input in the body of a POST.
    ApiErrorResponse
  • 415
    VALIDATION — a request body that is not JSON (application/json or application/*+json; a form body only on the OAuth token routes).Show moreVALIDATION — a request body that is not JSON (application/json or application/*+json; a form body only on the OAuth token routes). The public edge refuses it before the platform sees it (details.reason UNSUPPORTED_MEDIA_TYPE, details.source edge). Not retryable as sent: send Content-Type application/json. Declared on every operation that takes a JSON request body.
    ApiErrorResponse
  • 429RATE_LIMITED SIGNUP_RATE_LIMITED — more than 5 sign-ups for this e-mail or 20 for this domain today; or the address limits of IdentityRateLimited (details.action signup-device)ApiErrorResponse
  • 500INTERNAL — a bug, and traceId is the support handle.ApiErrorResponse
  • 501NOT_IMPLEMENTED DEVICE_SIGNUP_UNAVAILABLE — device-code sign-up is off on this deploymentApiErrorResponse

Errors you should handle

Branch on code and honour retryable — never on the HTTP status alone.

400VALIDATION
message.intent.checkOut must be after message.intent.checkIn
not retryable
400UNKNOWN_DOMAIN
Unknown domain 'HOTELS'. Did you mean HTL?
not retryable
405VALIDATION
This method is not served.
not retryable
413VALIDATION
The request body is larger than this API accepts (262144 bytes).
not retryable
414VALIDATION
The request URI is longer than 8 KiB.
not retryable
415VALIDATION
Send application/json.
not retryable
429RATE_LIMITED
Too many sign-ups for this e-mail today. Try again after the Retry-After interval.
retryable
500INTERNAL
An unexpected error occurred. Quote the traceId to support.
retryable
501NOT_IMPLEMENTED
Device-code sign-up is not available on this deployment. Sign up with POST /v1/signup.
not retryable