> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sentfrom.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Create an agent account

> Create a receive-only inbox and credentials before the human claims the account.

Requires the agent-onboarding API release. See [Set up your agent](/agent-install)
for credential handling, safe retries and the human claim flow.


## OpenAPI

````yaml POST /agent-signups
openapi: 3.1.0
info:
  title: SentFromAI API
  version: 0.1.0
  description: >-
    Comms infrastructure for AI agents. Email send/receive, threading,
    attachments, drafts, webhooks, realtime, and search.
servers:
  - url: https://api.sentfrom.ai/v1
security:
  - bearerAuth: []
tags:
  - name: account
    description: >-
      Agent bootstrap and human ownership claim status; signup requires the
      staged rollout to be enabled.
  - name: inboxes
  - name: messages
  - name: threads
  - name: drafts
  - name: webhooks
  - name: labels
  - name: lists
  - name: attachments
  - name: domains
    description: Custom sending domains
paths:
  /agent-signups:
    post:
      tags:
        - account
      summary: Create an agent account and inbox
      description: >-
        Staged rollout, disabled by default. Bootstrap through REST before
        connecting authenticated MCP. Persist a cryptographically random
        Idempotency-Key and exact request body before the first request. New
        accounts receive and read within limits, with sending and other changes
        disabled until a verified human explicitly claims the account. Save
        credentials privately. Retries with the same key and normalized body
        replay the original response for 60 minutes by default without rotating
        the API key. After expiry use the original key; do not create a
        replacement identity. Claiming preserves the tenant, inbox and API key.
      operationId: createAgentSignup
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          description: >-
            Credential-like high-entropy secret. Generate at least 32 random
            bytes encoded as URL-safe text, save privately before sending, and
            reuse with the exact saved body for retries. Never log this header.
          schema:
            type: string
            minLength: 32
            maxLength: 128
            pattern: ^[A-Za-z0-9_-]{32,128}$
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AgentSignupRequest'
            example:
              name: My agent
      responses:
        '200':
          description: >-
            Original signup response replayed; the inbox and API key are
            unchanged.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentSignupResponse'
        '201':
          description: Created; securely save the API key and claim link.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentSignupResponse'
        '400':
          description: >-
            invalid_request, invalid_address or invalid_idempotency_key: correct
            the request format.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OnboardingError'
        '409':
          description: >-
            idempotency_conflict: this secret was used with different signup
            details; reuse the original body. address_taken or address_reserved:
            requested local part unavailable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OnboardingError'
        '410':
          description: >-
            signup_replay_expired: the original signup succeeded, but its
            encrypted response expired. Use the saved API key or claimed console
            account. This secret never creates a second tenant.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OnboardingError'
        '413':
          description: Signup request body exceeds 4096 bytes.
        '429':
          description: >-
            Rate limited. Respect Retry-After before retrying; never create
            another signup identity to avoid a limit.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OnboardingError'
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
                minimum: 1
        '503':
          description: >-
            signup_disabled or signup_unavailable: rollout disabled or server
            prerequisites unavailable. Use an existing account or console
            signup.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OnboardingError'
      security: []
components:
  schemas:
    AgentSignupRequest:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 100
          description: >-
            Workspace display name. Trimmed; control characters are rejected.
            Defaults to Agent workspace.
        local_part:
          type: string
          minLength: 1
          maxLength: 64
          description: >-
            Optional inbox local part. Trimmed and lowercased; letters, digits,
            dots, underscores and hyphens, with a letter or digit at each end
            and no consecutive dots. Reserved or occupied names are rejected.
            Omit to allocate a name.
    AgentSignupResponse:
      type: object
      properties:
        tenant_id:
          type: string
        inbox:
          $ref: '#/components/schemas/AccountInbox'
        api_key:
          type: string
          format: password
          description: >-
            Save privately before proceeding. Bearer credential for this tenant;
            unchanged across signup replays and claiming.
        onboarding_state:
          type: string
          const: unclaimed
        capabilities:
          $ref: '#/components/schemas/AccountCapabilities'
        limits:
          $ref: '#/components/schemas/AccountLimits'
        unclaimed_expires_at:
          type: string
          format: date-time
          description: Account expiry unless claimed, seven days by default.
        claim_url:
          type: string
          format: uri
          description: >-
            Private console claim URL, with a separate bearer secret in the
            #token fragment. Share only with the operator in an existing trusted
            channel; never log or email it.
        claim_expires_at:
          type: string
          format: date-time
          description: >-
            Link expiry, default 30 minutes, bounded by account expiry. A new
            link does not extend account lifetime.
        instructions:
          type: array
          items:
            type: string
      required:
        - tenant_id
        - inbox
        - api_key
        - onboarding_state
        - capabilities
        - limits
        - unclaimed_expires_at
        - claim_url
        - claim_expires_at
        - instructions
    OnboardingError:
      type: object
      properties:
        error:
          type: string
          description: Machine-readable error code.
        message:
          type: string
          description: Explanation and recovery guidance.
      required:
        - error
    AccountInbox:
      type: object
      properties:
        id:
          type: string
        address:
          type: string
          format: email
      required:
        - id
        - address
    AccountCapabilities:
      type: object
      properties:
        receive:
          type: boolean
          description: Account may receive, subject to quotas and message limits.
        read:
          type: boolean
          description: Account may read its existing inbox and mail.
        send:
          type: boolean
          description: >-
            Account ownership and sending status permit sending. False while
            paused. Plan, warming, suppression and abuse checks still apply.
        manage:
          type: boolean
          description: >-
            Ownership permits resource mutations; plan limits still apply.
            Unclaimed accounts may only refresh claim links.
      required:
        - receive
        - read
        - send
        - manage
    AccountLimits:
      type: object
      properties:
        inboxes:
          type: integer
          minimum: 1
          description: Inbox cap. One while unclaimed; plan-specific after claim.
        received_messages:
          type:
            - integer
            - 'null'
          minimum: 0
          description: >-
            Cumulative unclaimed inbound message cap, default 50. Null means no
            onboarding-specific cap; plan limits still apply.
        received_bytes:
          type:
            - integer
            - 'null'
          minimum: 0
          description: >-
            Cumulative unclaimed inbound byte cap, default 10485760 (10 MiB).
            Null after claim; plan limits still apply.
      required:
        - inboxes
        - received_messages
        - received_bytes
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.