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

# Request data, acquiring a cache miss

> Get data that may not be published yet. Published coverage returns ready (free). An identical acquisition already running returns its request (free). Otherwise the request is acquired from the source for a fixed MPP price: the first call returns a payment challenge, and the paid retry returns a request ID and receipt. Poll the request until ready, then query. Requests outside source coverage are rejected before any charge. Over HTTP the challenge is a 402 with WWW-Authenticate: Payment (Stripe shared payment token); retry with Authorization: Payment and keep the same credential for any retry. Then POST the same body to /api/v1/data/query once ready.



## OpenAPI

````yaml /openapi.json post /api/v1/data/requests
openapi: 3.1.0
info:
  title: Verdant Climate Data API
  version: 1.0.0
  description: >-
    Versioned climate data with preserved meaning. Discover → inspect → resolve
    → query. Small published-data queries return values directly, with explicit
    units, spatial support, missingness and provenance. Reading published data
    requires no credentials. Missing coverage is acquired from the source on
    request through /api/v1/data/requests, paid per acquisition with MPP.
    Consult capabilities before planning a workflow.
servers:
  - url: https://api.verdant-ai.com
    description: Production
security: []
tags:
  - name: Discovery
  - name: Queries
  - name: Observations
  - name: Raster
  - name: Service
paths:
  /api/v1/data/requests:
    post:
      tags:
        - Queries
      summary: Request data, acquiring a cache miss
      description: >-
        Get data that may not be published yet. Published coverage returns ready
        (free). An identical acquisition already running returns its request
        (free). Otherwise the request is acquired from the source for a fixed
        MPP price: the first call returns a payment challenge, and the paid
        retry returns a request ID and receipt. Poll the request until ready,
        then query. Requests outside source coverage are rejected before any
        charge. Over HTTP the challenge is a 402 with WWW-Authenticate: Payment
        (Stripe shared payment token); retry with Authorization: Payment and
        keep the same credential for any retry. Then POST the same body to
        /api/v1/data/query once ready.
      operationId: requestData
      requestBody:
        required: true
        description: >-
          The same request body as /api/v1/data/query. Format does not change
          what is acquired.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DataRequest'
            example:
              variables:
                - air_temperature_max
              region:
                bbox:
                  - 142.3
                  - -34.45
                  - 142.4
                  - -34.35
                crs: EPSG:4326
              period:
                start: '2003-01-01'
                end: '2003-01-01'
              temporal_resolution: daily
              spatial_resolution: native
              units:
                air_temperature_max: degC
              data_class: interpolated_observation
              format: json
              missing_policy: preserve
              source_preference: silo
      responses:
        '200':
          description: 'Cache hit: published coverage already satisfies the request (free).'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataRequestReady'
        '202':
          description: >-
            Acquisition queued after payment, or an identical running
            acquisition (free). Poll the Location URL.
          headers:
            Location:
              description: Status URL for this acquisition.
              schema:
                type: string
            Retry-After:
              description: Suggested polling delay in seconds.
              schema:
                type: integer
            Payment-Receipt:
              description: MPP receipt when this call paid (or recovered a payment).
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataRequestStatus'
        '400':
          description: Empty, malformed JSON, or unreadable body.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '402':
          description: >-
            Payment required for a new acquisition. application/problem+json
            with the challenge in WWW-Authenticate.
          headers:
            WWW-Authenticate:
              description: MPP Payment challenge (method stripe, intent charge).
              schema:
                type: string
        '413':
          description: >-
            request_too_large: more than 31 days, 10,000 cells, or 256 cells per
            side.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '415':
          description: Content-Type must be application/json.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: >-
            Invalid contract, or an acquisition rejection:
            outside_source_coverage, no_cell_centers, dataset_version_pinned.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: >-
            payment_or_fulfillment_failed: retry with the same credential to
            recover without a second charge.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: Data service unavailable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - {}
        - mppPayment: []
        - bearerToken: []
components:
  schemas:
    DataRequest:
      type: object
      properties:
        variables:
          minItems: 1
          maxItems: 1
          type: array
          items:
            type: string
            enum:
              - air_temperature_max
              - air_temperature_min
              - precipitation_amount
        region:
          type: object
          properties:
            bbox:
              type: array
              prefixItems:
                - type: number
                  minimum: -180
                  maximum: 180
                - type: number
                  minimum: -90
                  maximum: 90
                - type: number
                  minimum: -180
                  maximum: 180
                - type: number
                  minimum: -90
                  maximum: 90
              items: false
              minItems: 4
              maxItems: 4
            crs:
              type: string
              const: EPSG:4326
          required:
            - bbox
            - crs
          additionalProperties: false
        period:
          type: object
          properties:
            start:
              type: string
              format: date
              pattern: >-
                ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))$
            end:
              type: string
              format: date
              pattern: >-
                ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))$
          required:
            - start
            - end
          additionalProperties: false
        temporal_resolution:
          type: string
          const: daily
        spatial_resolution:
          type: string
          const: native
        units:
          type: object
          properties:
            air_temperature_max:
              type: string
              const: degC
            air_temperature_min:
              type: string
              const: degC
            precipitation_amount:
              type: string
              const: mm
          additionalProperties: false
          description: Exactly one entry, for the requested variable.
        data_class:
          type: string
          const: interpolated_observation
        format:
          default: json
          type: string
          enum:
            - json
            - csv
        missing_policy:
          type: string
          const: preserve
        source_preference:
          default: auto
          description: >-
            auto picks the finest source covering the region: SILO (Australia),
            NOAA nClimGrid-Daily (contiguous US), NOAA CPC (global).
          type: string
          enum:
            - auto
            - silo
            - nclimgrid
            - cpc
        dataset_version:
          description: >-
            Pin an immutable published dataset version. Omit to choose a
            compatible public version.
          type: string
          pattern: ^[a-zA-Z0-9_-]{1,128}$
      required:
        - variables
        - region
        - period
        - temporal_resolution
        - spatial_resolution
        - units
        - data_class
        - missing_policy
      additionalProperties: false
      description: >-
        Data meaning is independent of representation and delivery. JSON
        (default) and CSV are returned inline. Bbox order:
        west,south,east,north; no antimeridian crossing. Date bounds inclusive;
        at most 31 days and 10,000 cells; actual coverage must pass resolve.
        dataset_version pins reproducibility.
    DataRequestReady:
      type: object
      properties:
        status:
          type: string
          const: ready
        cache:
          type: string
          const: hit
        datasetVersion:
          type: string
          pattern: ^[a-zA-Z0-9_-]{1,128}$
        rowCount:
          type: integer
          exclusiveMinimum: 0
          maximum: 9007199254740991
        links:
          type: object
          properties:
            self:
              type: string
            query:
              type: string
            dataset:
              type: string
          additionalProperties: false
      required:
        - status
        - cache
        - datasetVersion
        - rowCount
        - links
      additionalProperties: false
    DataRequestStatus:
      type: object
      properties:
        id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
        status:
          type: string
          enum:
            - queued
            - acquiring
            - normalizing
            - validating
            - publishing
            - ready
            - failed
        cache:
          type: string
          const: miss
        created:
          description: False when an identical in-flight or recent acquisition was reused.
          type: boolean
        coverageDigest:
          type: string
          pattern: ^[a-f0-9]{64}$
        target:
          type: object
          propertyNames:
            type: string
          additionalProperties: {}
        datasetVersion:
          anyOf:
            - type: string
              pattern: ^[a-zA-Z0-9_-]{1,128}$
            - type: 'null'
        error:
          anyOf:
            - type: object
              properties:
                reason:
                  type: string
              required:
                - reason
              additionalProperties: {}
            - type: 'null'
        createdAt:
          type: string
        updatedAt:
          type: string
        job:
          anyOf:
            - type: object
              properties:
                status:
                  type: string
                attempts:
                  type: integer
                  minimum: -9007199254740991
                  maximum: 9007199254740991
                maxAttempts:
                  type: integer
                  minimum: -9007199254740991
                  maximum: 9007199254740991
              required:
                - status
                - attempts
                - maxAttempts
              additionalProperties: false
            - type: 'null'
        events:
          type: array
          items:
            type: object
            properties:
              event:
                type: string
              details:
                type: object
                propertyNames:
                  type: string
                additionalProperties: {}
              at:
                type: string
            required:
              - event
              - details
              - at
            additionalProperties: false
        links:
          type: object
          properties:
            self:
              type: string
            query:
              type: string
            dataset:
              type: string
          additionalProperties: false
      required:
        - id
        - status
        - coverageDigest
        - target
        - datasetVersion
        - error
        - createdAt
        - updatedAt
        - links
      additionalProperties: false
    Error:
      type: object
      properties:
        error:
          type: string
        message:
          type: string
        issues:
          type: array
          items:
            type: object
            properties:
              code:
                type: string
              path:
                type: array
                items:
                  type:
                    - string
                    - number
              message:
                type: string
            required:
              - code
              - path
              - message
            additionalProperties: {}
      required:
        - error
      additionalProperties: {}
  securitySchemes:
    mppPayment:
      type: http
      scheme: payment
      description: >-
        Machine Payments Protocol credential for a new acquisition, issued in
        response to a 402 challenge.
    bearerToken:
      type: http
      scheme: bearer
      description: 'Operator token: queues acquisitions without payment.'

````

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