ProofDraw Draws API

The Draws API from ProofDraw — 6 operation(s) for draws.

Operations 8

GET /v1/draws List your draws
POST /v1/draws Create a draw
POST /v1/draws/instant Create, add entries, and seal in one call
GET /v1/draws/{id} Fetch a draw
DELETE /v1/draws/{id} Cancel an open draw
POST /v1/draws/{id}/entries Add entries in bulk
POST /v1/draws/{id}/seal Seal the draw
POST /v1/draws/{id}/resolve Resolve a sealed draw now

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/proofdraw-draws-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no email required.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

proofdraw-draws-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: ProofDraw Draws API
  version: 1.0.0
  description: 'Provably fair winner/loser selection. Every draw is sealed with SHA-256,

    decided by the drand public randomness beacon, and independently verifiable

    by anyone — in the browser, from public sources alone.


    **Flow**: create a draw → add entries → seal (the entry list + a *future*

    drand round are hashed together and committed publicly) → when the round

    arrives, `winner_row = drand_value mod N`. Or do it all in one call with

    `POST /v1/draws/instant`.


    **Envelope**: every response is `{ "success": bool, "data": …, "message": string }`.

    Errors add a machine-readable `code`.


    **Rate limits**: per API key. `X-RateLimit-Limit` and `X-RateLimit-Remaining`

    headers are returned on every response.

    '
  termsOfService: https://proofdraw.com/terms
  contact:
    name: ProofDraw
    email: hello@proofdraw.com
    url: https://proofdraw.com/contact
servers:
- url: https://proofdraw.com/api
  description: Production
security:
- bearerAuth: []
tags:
- name: Draws
paths:
  /v1/draws:
    get:
      tags:
      - Draws
      summary: List your draws
      description: Returns up to 100 most recent draws, newest first.
      responses:
        '200':
          description: Draws.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/Envelope'
                - type: object
                  properties:
                    data:
                      type: object
                      properties:
                        draws:
                          type: array
                          items:
                            $ref: '#/components/schemas/Draw'
        '401':
          $ref: '#/components/responses/Unauthenticated'
    post:
      tags:
      - Draws
      summary: Create a draw
      description: 'Creates a draw in state `open`. If `callback_url` is set, the response

        includes `callback_secret` (HMAC key for webhook signatures) — this is

        the **only** time it is returned.

        '
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DrawCreate'
      responses:
        '201':
          description: Draw created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DrawResponse'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/TierLimit'
        '422':
          $ref: '#/components/responses/ValidationFailed'
  /v1/draws/instant:
    post:
      tags:
      - Draws
      summary: Create, add entries, and seal in one call
      description: 'The recommended endpoint when you already have the full entrant list.

        With `wait: true`, blocks until the drand round arrives (~32–35 s with

        quicknet defaults) and returns the **resolved** draw with the winner.

        If create + entries succeed but the seal step fails, the open draw and

        tickets are returned with HTTP 500 / `code: seal_failed` — retry via

        `POST /v1/draws/{id}/seal`.

        '
      requestBody:
        required: true
        content:
          application/json:
            schema:
              allOf:
              - $ref: '#/components/schemas/DrawCreate'
              - type: object
                required:
                - entries
                properties:
                  entries:
                    type: array
                    minItems: 1
                    maxItems: 5000
                    items:
                      $ref: '#/components/schemas/EntryInput'
                  round_offset_seconds:
                    type: integer
                    minimum: 15
                    maximum: 604800
                    default: 30
                  wait:
                    type: boolean
                    default: false
      responses:
        '201':
          description: Draw sealed (and resolved, when `wait` was true and the round arrived in time).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SealedDrawResponse'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/TierLimit'
        '409':
          $ref: '#/components/responses/StateConflict'
        '422':
          $ref: '#/components/responses/ValidationFailed'
        '500':
          description: 'Draw + entries persisted but the seal step failed (`code: seal_failed`). Retry the seal.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /v1/draws/{id}:
    parameters:
    - $ref: '#/components/parameters/DrawId'
    get:
      tags:
      - Draws
      summary: Fetch a draw
      responses:
        '200':
          description: The draw in its current state.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DrawResponse'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '404':
          $ref: '#/components/responses/NotFound'
    delete:
      tags:
      - Draws
      summary: Cancel an open draw
      description: Only draws in state `open` can be cancelled. Sealed draws are public commitments and cannot be erased.
      responses:
        '200':
          description: Draw cancelled.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DrawResponse'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/StateConflict'
  /v1/draws/{id}/entries:
    parameters:
    - $ref: '#/components/parameters/DrawId'
    post:
      tags:
      - Draws
      summary: Add entries in bulk
      description: 'Up to 5,000 entries per request. `ticket_id` is optional — omit it and

        the server generates a Crockford-Base32 ticket. Supplied tickets must

        match `[A-Za-z0-9_\-\.]+` and be unique within the draw.

        '
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - entries
              properties:
                entries:
                  type: array
                  minItems: 1
                  maxItems: 5000
                  items:
                    $ref: '#/components/schemas/EntryInput'
      responses:
        '201':
          description: Entries added.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/Envelope'
                - type: object
                  properties:
                    data:
                      type: object
                      properties:
                        added:
                          type: integer
                        entry_count:
                          type: integer
                        tickets:
                          type: array
                          items:
                            type: string
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/StateConflict'
        '422':
          $ref: '#/components/responses/ValidationFailed'
  /v1/draws/{id}/seal:
    parameters:
    - $ref: '#/components/parameters/DrawId'
    post:
      tags:
      - Draws
      summary: Seal the draw
      description: 'Freezes the entry list: picks a future drand round, renders the

        canonical v2 list file (the round is in the header, so one SHA-256

        binds list **and** round), pushes it to the public

        `proofdraw/draw-lists` git mirror, and submits the hash to an

        OpenTimestamps calendar. The commit must land at least 10 s before the

        round publishes or the seal aborts. With `wait: true`, holds the

        connection until the round arrives and returns the resolved draw

        (bounded by the server''s wait cap, default 60 s).

        '
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                round_offset_seconds:
                  type: integer
                  minimum: 15
                  maximum: 604800
                  default: 30
                wait:
                  type: boolean
                  default: false
      responses:
        '200':
          description: Draw sealed (resolved when `wait` was true and the round arrived in time).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SealedDrawResponse'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/StateConflict'
  /v1/draws/{id}/resolve:
    parameters:
    - $ref: '#/components/parameters/DrawId'
    post:
      tags:
      - Draws
      summary: Resolve a sealed draw now
      description: 'Fetches the committed drand round and computes

        `winner_row = drand_value mod N`. Draws also auto-resolve within ~60 s

        of the round time; use this endpoint when you need the result the

        moment it is available. Idempotent on already-resolved draws.

        '
      responses:
        '200':
          description: Resolved draw.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DrawResponse'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: Not sealed (`state_conflict`), or the drand round has not been published yet (`not_yet_available`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: drand API unreachable (`drand_unavailable`) — transient, retry.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    SealedDrawResponse:
      allOf:
      - $ref: '#/components/schemas/Envelope'
      - type: object
        properties:
          data:
            type: object
            properties:
              draw:
                allOf:
                - $ref: '#/components/schemas/Draw'
                - type: object
                  properties:
                    commitment_text:
                      type: string
                      description: Publish this to a public
                      timestamped channel before the round time.: null
                    tweet_intent_url:
                      type: string
                      description: One-click X post of the commitment.
                    tickets:
                      type: array
                      items:
                        type: string
                      description: 'Instant endpoint only: all ticket ids in submission order.'
    EntryInput:
      type: object
      properties:
        ticket_id:
          type: string
          maxLength: 64
          pattern: ^[A-Za-z0-9_\-\.]+$
          description: Optional — omit to auto-generate. Your own customer ids, order numbers, or email hashes all work.
        metadata:
          type:
          - object
          - 'null'
          description: Opaque to ProofDraw; stored as-is.
    Draw:
      type: object
      properties:
        id:
          type: string
          example: K7M2
        name:
          type: string
        description:
          type:
          - string
          - 'null'
        state:
          type: string
          enum:
          - open
          - sealed
          - resolved
          - cancelled
        direction:
          type: string
          enum:
          - winner
          - loser
        winner_count:
          type: integer
        entry_count:
          type: integer
        drand_chain:
          type: string
          enum:
          - quicknet
          - classic
        drand_round:
          type:
          - integer
          - 'null'
          format: int64
        drand_round_time:
          type:
          - string
          - 'null'
          format: date-time
        list_hash:
          type:
          - string
          - 'null'
          description: SHA-256 over the sealed list bytes.
        list_url:
          type:
          - string
          - 'null'
        verify_url:
          type:
          - string
          - 'null'
          description: Public per-draw verification page.
        winner_row:
          type:
          - integer
          - 'null'
          description: 0-based index into the sealed list.
        winner_ticket:
          type:
          - string
          - 'null'
        callback_url:
          type:
          - string
          - 'null'
        callback_secret:
          type:
          - string
          - 'null'
          description: Returned only on the creating response. HMAC key for webhook signatures.
        public_commit_url:
          type:
          - string
          - 'null'
        sealed_at:
          type:
          - string
          - 'null'
          format: date-time
        resolved_at:
          type:
          - string
          - 'null'
          format: date-time
        created_at:
          type: string
          format: date-time
        ots_proof_url:
          type:
          - string
          - 'null'
        ots_calendar_url:
          type:
          - string
          - 'null'
        ots_attested_at:
          type:
          - string
          - 'null'
          format: date-time
    Error:
      type: object
      properties:
        success:
          type: boolean
          example: false
        data: {}
        message:
          type: string
        code:
          type: string
          enum:
          - validation_failed
          - unauthenticated
          - tier_limit_exceeded
          - not_found
          - state_conflict
          - not_yet_available
          - entry_limit_exceeded
          - rate_limited
          - seal_failed
          - internal_error
          - drand_unavailable
    DrawCreate:
      type: object
      required:
      - name
      properties:
        name:
          type: string
          maxLength: 120
        description:
          type:
          - string
          - 'null'
          maxLength: 2000
        direction:
          type: string
          enum:
          - winner
          - loser
          default: winner
        winner_count:
          type: integer
          minimum: 1
          maximum: 1
          default: 1
          description: Multi-winner draws are enterprise-only in v1.
        drand_chain:
          type: string
          enum:
          - quicknet
          - classic
          default: quicknet
        callback_url:
          type:
          - string
          - 'null'
          maxLength: 500
          description: Webhook target for draw.sealed / draw.resolved / draw.cancelled events.
        metadata:
          type:
          - object
          - 'null'
          description: Opaque
          max 4 KB.: null
    Envelope:
      type: object
      properties:
        success:
          type: boolean
          example: true
        message:
          type: string
          example: ''
    DrawResponse:
      allOf:
      - $ref: '#/components/schemas/Envelope'
      - type: object
        properties:
          data:
            type: object
            properties:
              draw:
                $ref: '#/components/schemas/Draw'
  responses:
    StateConflict:
      description: Operation not valid in the draw's current state (`state_conflict`).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: Draw not found or not yours (`not_found`).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    ValidationFailed:
      description: Invalid payload (`validation_failed` / `entry_limit_exceeded`).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    TierLimit:
      description: Plan draw cap reached (`tier_limit_exceeded`).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthenticated:
      description: Missing or invalid API key (`unauthenticated`).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  parameters:
    DrawId:
      name: id
      in: path
      required: true
      description: Draw public id — 4 uppercase Crockford-Base32 characters.
      schema:
        type: string
        pattern: ^[0-9A-Z]{4}$
        example: K7M2
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'API key: `Authorization: Bearer pd_live_…` (or `pd_test_…` for sandbox keys).'
externalDocs:
  description: Human-readable API documentation
  url: https://proofdraw.com/api