REST API · signup
POST /signup
Create an account. Body: `{email, password, accepted_legal}`. Step 1 of 4, and the only place a caller holding no token can start.
`accepted_legal` names the SHA-256 of the Terms of Service and the Privacy Policy the account accepts, as `GET /legal/current` gives them; the acceptance is recorded at the moment the account is created. A confirmation link goes to the address; nothing in this reply stands in for it, so step 2 needs a mailbox the caller can read. Sign-ups are limited per source address, and a refused request spends one of those attempts, so read the 422 or 409 rather than retrying blind.
post_api_signup
Authentication
None
Request body
application/json · required
{
"email": "agent@example.com",
"password": "A-Very-Str0ng-Signup-Password!",
"accepted_legal": {
"terms_of_service": "5f2a4c0e0b9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f",
"privacy_policy": "9c1b7d3e5f7a9b1c3d5e7f9a1b3c5d7e9f1a3b5c7d9e1f3a5b7c9d1e3f5a7b9c"
}
}
Responses
202
The account exists and the confirmation link is on its way.
application/json
{
"state": "pending_email_verification"
}
409
The rules changed: a SHA-256 in `accepted_legal` is no longer the newest published one. `current_legal` carries the current values; read them and send again.
application/json
{
"required": [
"error"
],
"properties": {
"error": {
"description": "Machine-readable error code, e.g. \"not_found\", \"forbidden\", \"validation\".",
"type": "string",
"enum": [
"bad_request",
"unauthorized",
"insufficient_credits",
"forbidden",
"web_only",
"allowlist_widens",
"not_found",
"conflict",
"draft_revision_conflict",
"rollback_confirmation_conflict",
"not_replayable",
"targets_outside_allowlist",
"gone",
"deprecated_operation",
"validation",
"rate_limited",
"payment_provider",
"verification_unavailable",
"analytics_unavailable",
"credential_vault_unavailable",
"notification_grants_unavailable"
]
},
"message": {
"description": "Human-readable explanation of what went wrong. Absent on a field-level validation failure, where `fields` carries the detail instead.",
"type": "string"
},
"object": {
"description": "The resource the error concerns, when there is one.",
"required": [
"type",
"id"
],
"properties": {
"type": {
"type": "string"
},
"id": {
"type": "string"
}
},
"type": "object"
},
"action": {
"description": "What to do next, naming the call or the panel page that does it. Absent when there is no corrective step.",
"type": "string"
},
"fields": {
"description": "Present when `error` is \"validation\" — one message per rejected field, keyed by the field name.",
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"retry_after": {
"description": "An RFC 3339 timestamp, the moment the request may be retried. Not every `rate_limited` refusal carries one.",
"type": "string",
"format": "date-time"
}
},
"type": "object"
}
422
The address, the password or `accepted_legal` was refused; `current_legal` carries the values to accept. A password needs at least 15 characters.
application/json
{
"required": [
"error"
],
"properties": {
"error": {
"description": "Machine-readable error code, e.g. \"not_found\", \"forbidden\", \"validation\".",
"type": "string",
"enum": [
"bad_request",
"unauthorized",
"insufficient_credits",
"forbidden",
"web_only",
"allowlist_widens",
"not_found",
"conflict",
"draft_revision_conflict",
"rollback_confirmation_conflict",
"not_replayable",
"targets_outside_allowlist",
"gone",
"deprecated_operation",
"validation",
"rate_limited",
"payment_provider",
"verification_unavailable",
"analytics_unavailable",
"credential_vault_unavailable",
"notification_grants_unavailable"
]
},
"message": {
"description": "Human-readable explanation of what went wrong. Absent on a field-level validation failure, where `fields` carries the detail instead.",
"type": "string"
},
"object": {
"description": "The resource the error concerns, when there is one.",
"required": [
"type",
"id"
],
"properties": {
"type": {
"type": "string"
},
"id": {
"type": "string"
}
},
"type": "object"
},
"action": {
"description": "What to do next, naming the call or the panel page that does it. Absent when there is no corrective step.",
"type": "string"
},
"fields": {
"description": "Present when `error` is \"validation\" — one message per rejected field, keyed by the field name.",
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"retry_after": {
"description": "An RFC 3339 timestamp, the moment the request may be retried. Not every `rate_limited` refusal carries one.",
"type": "string",
"format": "date-time"
}
},
"type": "object"
}
429
Too many sign-ups from this source address.
application/json
{
"required": [
"error"
],
"properties": {
"error": {
"description": "Machine-readable error code, e.g. \"not_found\", \"forbidden\", \"validation\".",
"type": "string",
"enum": [
"bad_request",
"unauthorized",
"insufficient_credits",
"forbidden",
"web_only",
"allowlist_widens",
"not_found",
"conflict",
"draft_revision_conflict",
"rollback_confirmation_conflict",
"not_replayable",
"targets_outside_allowlist",
"gone",
"deprecated_operation",
"validation",
"rate_limited",
"payment_provider",
"verification_unavailable",
"analytics_unavailable",
"credential_vault_unavailable",
"notification_grants_unavailable"
]
},
"message": {
"description": "Human-readable explanation of what went wrong. Absent on a field-level validation failure, where `fields` carries the detail instead.",
"type": "string"
},
"object": {
"description": "The resource the error concerns, when there is one.",
"required": [
"type",
"id"
],
"properties": {
"type": {
"type": "string"
},
"id": {
"type": "string"
}
},
"type": "object"
},
"action": {
"description": "What to do next, naming the call or the panel page that does it. Absent when there is no corrective step.",
"type": "string"
},
"fields": {
"description": "Present when `error` is \"validation\" — one message per rejected field, keyed by the field name.",
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"retry_after": {
"description": "An RFC 3339 timestamp, the moment the request may be retried. Not every `rate_limited` refusal carries one.",
"type": "string",
"format": "date-time"
}
},
"type": "object"
}
503
The confirmation mail could not be sent, so the account was not kept. Retry.
application/json
{
"required": [
"error"
],
"properties": {
"error": {
"description": "Machine-readable error code, e.g. \"not_found\", \"forbidden\", \"validation\".",
"type": "string",
"enum": [
"bad_request",
"unauthorized",
"insufficient_credits",
"forbidden",
"web_only",
"allowlist_widens",
"not_found",
"conflict",
"draft_revision_conflict",
"rollback_confirmation_conflict",
"not_replayable",
"targets_outside_allowlist",
"gone",
"deprecated_operation",
"validation",
"rate_limited",
"payment_provider",
"verification_unavailable",
"analytics_unavailable",
"credential_vault_unavailable",
"notification_grants_unavailable"
]
},
"message": {
"description": "Human-readable explanation of what went wrong. Absent on a field-level validation failure, where `fields` carries the detail instead.",
"type": "string"
},
"object": {
"description": "The resource the error concerns, when there is one.",
"required": [
"type",
"id"
],
"properties": {
"type": {
"type": "string"
},
"id": {
"type": "string"
}
},
"type": "object"
},
"action": {
"description": "What to do next, naming the call or the panel page that does it. Absent when there is no corrective step.",
"type": "string"
},
"fields": {
"description": "Present when `error` is \"validation\" — one message per rejected field, keyed by the field name.",
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"retry_after": {
"description": "An RFC 3339 timestamp, the moment the request may be retried. Not every `rate_limited` refusal carries one.",
"type": "string",
"format": "date-time"
}
},
"type": "object"
}