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

# Create an API key

> Creates a new API key, its associated AutoBoy user and wallet. Call this first — it needs no credentials, and every other endpoint takes the key it returns.

- The plaintext `apiKey` is returned **exactly once** and is never recoverable afterwards.
- Provisioning takes **~1–2s** as it creates a Privy account and an on-chain smart wallet.
- `label` must be unique across all keys. If it is taken you get a `409` — retry with a different one.
- Rate limited per IP. Over the limit returns a `429`.



## OpenAPI

````yaml https://thefirm.biz/api/public/v1/openapi.json post /api/public/v1/api-keys
openapi: 3.1.0
info:
  title: AutoBoy Public API
  version: 0.1.0
  description: >-
    REST API for AutoBoy — browse projects, view detailed stats about your own
    launch, create buy orders and manage your AutoBoy smart wallet.


    ## Authentication


    Most endpoints require an API key, sent as a bearer token:


    ```

    Authorization: Bearer autoboy_…

    ```


    Keys are self-serve — `POST /api/public/v1/api-keys` returns one
    immediately, no approval needed.


    ## Rate limiting


    - With an API key: 100 requests per minute.

    - Creating an API key: limited per IP.


    ## Quick start


    - **Buying tokens?** Create a key — `POST /api/public/v1/api-keys` — then
    place buy orders.

    - **Launching a token?** Create a key, then register your project — `POST
    /api/public/v1/projects`.


    New to AutoBoy? Read the product docs https://docs.thefirm.biz.
servers:
  - url: https://thefirm.biz
security: []
tags:
  - name: API Keys
    description: Create API keys.
  - name: Identity
    description: Inspect the identity behind your API key.
  - name: Projects
    description: Browse projects and their buyers.
  - name: Buy Orders
    description: Read and manage the API key owner's pre-launch buy orders.
  - name: AutoBoy Wallet
    description: Balances of, and withdrawals from, the AutoBoy smart wallet.
  - name: Feedback
    description: Send feedback to The Firm.
paths:
  /api/public/v1/api-keys:
    post:
      tags:
        - API Keys
      summary: Create an API key
      description: >-
        Creates a new API key, its associated AutoBoy user and wallet. Call this
        first — it needs no credentials, and every other endpoint takes the key
        it returns.


        - The plaintext `apiKey` is returned **exactly once** and is never
        recoverable afterwards.

        - Provisioning takes **~1–2s** as it creates a Privy account and an
        on-chain smart wallet.

        - `label` must be unique across all keys. If it is taken you get a `409`
        — retry with a different one.

        - Rate limited per IP. Over the limit returns a `429`.
      operationId: createApiKey
      requestBody:
        required: true
        description: Metadata for the new key.
        content:
          application/json:
            schema:
              type: object
              properties:
                label:
                  type: string
                  minLength: 1
                  maxLength: 100
                  description: >-
                    Human-readable name to identify this key, e.g. "arca-bot".


                    - Trimmed and lowercased before storage.

                    - Must be unique across all keys, so pick something specific
                    to you. A taken label returns a 409.
              required:
                - label
      responses:
        '201':
          description: The API key was created and its smart wallet provisioned.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateApiKeyResponse'
              example:
                apiKey: autoboy_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ
                autoboyWalletAddress: '0x1234567890123456789012345678901234567890'
        '400':
          description: Invalid or missing request body (e.g. missing label).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: The caller is deny-listed and blocked from this endpoint.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error: Forbidden
                message: Request blocked.
        '409':
          description: >-
            This label is already taken, or is still being provisioned by a
            concurrent request — `code` distinguishes the two.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateApiKeyConflictResponse'
              examples:
                provisioningInProgress:
                  value:
                    error: Conflict
                    code: provisioning_in_progress
                    message: >-
                      A key for this label is still being provisioned by another
                      request. Retry the same label for the final status. The
                      key is returned only once, to the request that created it
                      — if that response was lost, create a new key with a
                      different label.
                alreadyProvisioned:
                  value:
                    error: Conflict
                    code: already_provisioned
                    message: >-
                      That label is already taken. Labels are unique across all
                      API keys, and a key is shown only once and cannot be
                      retrieved again. Retry with a different label to create a
                      new key.
        '429':
          description: Rate limit exceeded. Wait `Retry-After` seconds before retrying.
          headers:
            Retry-After:
              description: Seconds until the rate-limit window resets.
              schema:
                type: integer
            X-RateLimit-Limit:
              description: Request limit for the current window.
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: Requests remaining in the current window.
              schema:
                type: integer
            X-RateLimit-Reset:
              description: Epoch milliseconds at which the window resets.
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error: Too many requests
                message: Rate limit exceeded. Retry after the window resets.
        '500':
          description: Failed to create the API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: >-
            Rate limiting is unavailable, so key creation is paused. Wait
            `Retry-After` seconds before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    CreateApiKeyResponse:
      type: object
      properties:
        apiKey:
          type: string
          description: >-
            The plaintext API key. Returned exactly once — it is never stored in
            plaintext and cannot be retrieved again. Store it securely on
            receipt; if lost, create a new key with a different label.
          example: autoboy_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ
        autoboyWalletAddress:
          type: string
          description: On-chain smart wallet address provisioned for this key.
          example: '0x1234567890123456789012345678901234567890'
      required:
        - apiKey
        - autoboyWalletAddress
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
        message:
          type: string
      required:
        - error
        - message
      example:
        error: Bad request
        message: Invalid request body
    CreateApiKeyConflictResponse:
      type: object
      properties:
        error:
          type: string
          description: Short HTTP error label, always "Conflict".
        code:
          type: string
          enum:
            - already_provisioned
            - provisioning_in_progress
          description: >-
            Machine-readable conflict reason. `provisioning_in_progress`:
            another request is still creating a key for this label — retry the
            same label for the final status. `already_provisioned`: the label is
            taken and its key cannot be retrieved.
        message:
          type: string
          description: Human-readable explanation of the conflict.
      required:
        - error
        - code
        - message

````