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

# Upload a coin's image and details

> JSON `{ authorizationBase64, image: { type, base64 } }`, where `authorizationBase64` is the base64 of the authorization JSON `{ owner, deploymentId, issuedAt, metadata }` plus `signatureBase64` if the upload is signed (optional; the message is described in the Launch a coin guide). Send it base64-encoded: the CDN refuses bodies that look like HTML with an HTML 403. A plain `authorization` object and multipart (`image`, `authorization` as a JSON string) are still accepted. Re-uploading the same content returns the same record.



## OpenAPI

````yaml /openapi.json post /api/metadata
openapi: 3.1.0
info:
  title: RUNNERS Launch API
  version: 1.3.0
  summary: Launch a Solana coin from an agent or bot.
  description: >-
    Upload coin metadata, estimate launch costs, prepare unsigned launch
    transactions, sign locally, submit and confirm. All amounts use integer
    base-unit strings. No website session or integrator API key is required. See
    the Launch a coin guide for the optional authorization messages and the
    launchpad signer.
servers:
  - url: https://runners.family
    description: RUNNERS production API (Solana mainnet)
security: []
tags:
  - name: Launch
    description: >-
      Launch a coin from any HTTP client with an ed25519 keypair: upload the
      image and details, prepare (one transaction when a shared config exists
      for the quote token's price band, otherwise two), sign with the listed
      signers, submit (optionally relayed) and confirm. The launch transactions
      the creator's wallet signs authorize the coin; wallet message signatures
      for the upload and the preparation are optional. See the Launch a coin
      guide.
paths:
  /api/metadata:
    post:
      tags:
        - Launch
      summary: Upload a coin's image and details
      description: >-
        JSON `{ authorizationBase64, image: { type, base64 } }`, where
        `authorizationBase64` is the base64 of the authorization JSON `{ owner,
        deploymentId, issuedAt, metadata }` plus `signatureBase64` if the upload
        is signed (optional; the message is described in the Launch a coin
        guide). Send it base64-encoded: the CDN refuses bodies that look like
        HTML with an HTML 403. A plain `authorization` object and multipart
        (`image`, `authorization` as a JSON string) are still accepted.
        Re-uploading the same content returns the same record.
      operationId: uploadMetadata
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - image
              properties:
                authorizationBase64:
                  type: string
                  contentEncoding: base64
                  description: >-
                    Base64 of the authorization JSON (preferred over
                    `authorization`).
                authorization:
                  type: object
                  description: >-
                    The authorization as a JSON object; the CDN may refuse it if
                    the coin details look like HTML.
                image:
                  type: object
                  required:
                    - type
                    - base64
                  properties:
                    type:
                      type: string
                      enum:
                        - image/png
                        - image/jpeg
                        - image/gif
                        - image/webp
                    base64:
                      type: string
                      contentEncoding: base64
          multipart/form-data:
            schema:
              type: object
      responses:
        '200':
          description: Stored upload.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StoredMetadata'
        '401':
          description: >-
            Bad signature (`signature_invalid`) or expired authorization
            (`authorization_expired`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LaunchError'
        '403':
          description: A different site's Origin (`origin_forbidden`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LaunchError'
        '413':
          description: '`request_too_large`.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LaunchError'
        '422':
          description: '`request_invalid` or `image_invalid`.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LaunchError'
        '429':
          description: >-
            Identical-content retry limit, configured storage budget or
            request-rate limit.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LaunchError'
components:
  schemas:
    StoredMetadata:
      type: object
      properties:
        id:
          type: string
        namespace:
          type: string
        owner:
          $ref: '#/components/schemas/Address'
        digest:
          type: string
        uri:
          type: string
        imageUri:
          type: string
        imageType:
          type: string
        metadata:
          type: object
    LaunchError:
      type: object
      required:
        - error
        - code
      properties:
        error:
          type: string
        code:
          type: string
          enum:
            - request_invalid
            - signature_invalid
            - authorization_expired
            - origin_forbidden
            - network_changed
            - unavailable
            - metadata_required
            - draft_changed
            - draft_not_found
            - draft_not_ready
            - already_submitted
            - not_retryable
            - upload_limit
            - price_unavailable
            - quote_unpriced
            - quote_illiquid
            - price_pending
            - price_changed
            - estimate_expired
            - estimate_changed
            - unsupported_quote
            - standard_pair_sol
            - transfer_fee_quote_unsupported
            - first_buy_too_large
            - first_buy_invalid
            - transaction_invalid
            - transaction_mismatch
            - transaction_expired
            - not_found
            - conflict
            - request_too_large
            - image_invalid
            - rate_limited
            - insufficient_funds
            - config_required
            - unsent_limit
    Address:
      type: string
      pattern: ^[1-9A-HJ-NP-Za-km-z]{32,44}$
      description: Base58 Solana address.
      examples:
        - So11111111111111111111111111111111111111112

````

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