API referenceidentity
Start device signup
POST
/v1/signup/deviceStart 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 more
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 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 more
The 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 more
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 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
- 405ApiErrorResponse
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 more
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). Not retryable as sent. - 413ApiErrorResponse
VALIDATION — the request body is larger than the surface's limit.Show more
VALIDATION — 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. - 414ApiErrorResponse
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 more
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). Not retryable as sent: send long input in the body of a POST. - 415ApiErrorResponse
VALIDATION — a request body that is not JSON (application/json or application/*+json; a form body only on the OAuth token routes).Show more
VALIDATION — 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. - 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.
| 400 | VALIDATION message.intent.checkOut must be after message.intent.checkIn | not retryable |
| 400 | UNKNOWN_DOMAIN Unknown domain 'HOTELS'. Did you mean HTL? | not retryable |
| 405 | VALIDATION This method is not served. | not retryable |
| 413 | VALIDATION The request body is larger than this API accepts (262144 bytes). | not retryable |
| 414 | VALIDATION The request URI is longer than 8 KiB. | not retryable |
| 415 | VALIDATION Send application/json. | not retryable |
| 429 | RATE_LIMITED Too many sign-ups for this e-mail today. Try again after the Retry-After interval. | retryable |
| 500 | INTERNAL An unexpected error occurred. Quote the traceId to support. | retryable |
| 501 | NOT_IMPLEMENTED Device-code sign-up is not available on this deployment. Sign up with POST /v1/signup. | not retryable |