Create an end-user
Create a new end-user within a space. At least one of name, email, or externalId should be provided for identification. The space named by X-Space-Id must be a TEAM space: a personal space takes no end-users (409 personal_space_takes_no_end_users), because an end-user is an external identity signing in to a space that exists for exactly one member and goes away with them.
/api/end-usersCookie session from Better Auth. Requires X-Org-Id header for org-scoped routes.
In: cookie
Header Parameters
Organization ID. Required for cookie auth. Not needed for API key auth (org resolved from key).
uuidSpace ID. Required for space-scoped routes (agents, runs, schedules, and space-scoped module routes). Not needed for API key auth (space resolved from key).
Unique key for idempotent requests (max 255 chars). Prevents duplicate resource creation on retries. Cached for 24 hours, scoped to the organization and space: a repeat with the same method, URL and body replays the original response with Idempotent-Replayed: true, the same key with a different method, URL or body is 422 idempotency_conflict, and a concurrent duplicate is 409 idempotency_in_progress. Current permissions are checked again; run responses are projected using current visibility. This operation honours the header because it declares this parameter — operations that do not declare it refuse the header with 400 idempotency_not_supported rather than silently ignoring it (see the “Idempotency” section of the API description).
length <= 255Request Body
application/json
curl -X POST "https://your-instance/api/end-users" \ -H "Content-Type: application/json" \ -d '{ "name": "Alice Martin", "email": "[email protected]", "externalId": "usr_12345", "metadata": { "plan": "pro", "region": "eu-west" } }'{
"id": "eu_cm4jkl012",
"object": "end_user",
"spaceId": "spc_2c5d8f1a-4b70-4e63-9d18-3a7f5c9e0b24",
"name": "Alice Martin",
"email": "[email protected]",
"externalId": "usr_12345",
"metadata": {
"plan": "pro",
"region": "eu-west"
},
"createdAt": "2026-01-15T10:30:00Z",
"updatedAt": "2026-01-15T10:30:00Z"
}{
"type": "https://docs.appstrate.dev/errors/validation-failed",
"title": "Validation Failed",
"status": 400,
"detail": "name: Invalid input: expected string, received undefined (+2 more)",
"code": "validation_failed",
"request_id": "req_abc123",
"errors": [
{
"field": "name",
"code": "required",
"message": "Invalid input: expected string, received undefined"
},
{
"field": "email",
"code": "invalid_format",
"message": "Invalid email address"
},
{
"field": "age",
"code": "invalid_type",
"message": "Invalid input: expected number, received string"
}
]
}{
"type": "https://docs.appstrate.dev/errors/unauthorized",
"title": "Unauthorized",
"status": 401,
"detail": "Invalid or missing session",
"code": "unauthorized",
"request_id": "req_abc123"
}{
"type": "https://docs.appstrate.dev/errors/forbidden",
"title": "Forbidden",
"status": 403,
"detail": "Insufficient permissions",
"code": "forbidden",
"request_id": "req_abc123"
}{
"type": "https://docs.appstrate.dev/errors/not-found",
"title": "Not Found",
"status": 404,
"detail": "Resource not found",
"code": "not_found",
"request_id": "req_abc123"
}{
"type": "https://docs.appstrate.dev/errors/idempotency-in-progress",
"title": "Idempotency In Progress",
"status": 409,
"detail": "A request with the same Idempotency-Key is already being processed. Please wait and retry.",
"code": "idempotency_in_progress",
"request_id": "req_abc123"
}{
"type": "https://docs.appstrate.dev/errors/idempotency-conflict",
"title": "Idempotency Conflict",
"status": 422,
"detail": "This Idempotency-Key was already used with a different method, URL or body. Use a new key for different requests.",
"code": "idempotency_conflict",
"request_id": "req_abc123"
}{
"type": "https://docs.appstrate.dev/errors/rate-limited",
"title": "Rate Limited",
"status": 429,
"detail": "Too many requests. Please try again shortly.",
"code": "rate_limited",
"request_id": "req_abc123",
"retry_after": 30
}