Context.dev Batch API

Submit up to 25,000 URLs or a whole-site crawl as a single asynchronous job and collect the results as paginated JSON or gzipped NDJSON. One batch submission counts as a single request against the per-minute rate limit however many pages it covers, and POST /batch/submit is the only Context.dev operation that accepts an Idempotency-Key header. 6 operation(s) for batch scraping and crawling.

OpenAPI Specification

contextdev-batch-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Context.dev Batch API
  description: Scrape many pages or crawl a site asynchronously with the Context.dev Batch API. Harvested verbatim from the
    per-operation OpenAPI fragments published on https://docs.context.dev/api-reference/batches/*.
  version: 1.0.0
servers:
- url: https://api.context.dev/v1
tags:
- name: Batch
  description: Scrape many pages or crawl a site asynchronously.
paths:
  /batch/list:
    get:
      tags:
      - Batch
      summary: List batches
      description: List your batches from newest to oldest. Filter by status or continue with a cursor.
      operationId: listBatches
      parameters:
      - schema:
          type: integer
          minimum: 1
          maximum: 100
          description: Batches per page. Defaults to 25.
        required: false
        description: Batches per page. Defaults to 25.
        name: limit
        in: query
      - schema:
          type: string
          description: Cursor from the previous page.
        required: false
        description: Cursor from the previous page.
        name: cursor
        in: query
      - schema:
          type: string
          enum:
          - queued
          - running
          - cancelling
          - completed
          - cancelled
          - failed
          description: Filter by status.
        required: false
        description: Filter by status.
        name: status
        in: query
      - schema:
          type: string
          maxLength: 200
          description: Free-text search term, matched against the batch id, crawl source (start URL or sitemap domain), and
            tags.
          example: batch_1a2b
        required: false
        description: Free-text search term, matched against the batch id, crawl source (start URL or sitemap domain), and
          tags.
        name: q
        in: query
      - schema:
          type: string
          enum:
          - exact
          - prefix
          description: '`prefix` for as-you-type prefix matching (default), `exact` for full-token matching.'
        required: false
        description: '`prefix` for as-you-type prefix matching (default), `exact` for full-token matching.'
        name: search_type
        in: query
      - schema:
          type: string
          description: Comma-separated list of tags to filter by (matches batches having any of them).
          example: docs,competitor
        required: false
        description: Comma-separated list of tags to filter by (matches batches having any of them).
        name: tags
        in: query
      responses:
        '200':
          description: Your batches, newest first. Use `next_cursor` to page through the rest.
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Batch'
                    description: Batches on this page.
                  has_more:
                    type: boolean
                    description: Whether another page is available.
                  next_cursor:
                    type: string
                    nullable: true
                    description: Cursor for the next page.
                  key_metadata:
                    $ref: '#/components/schemas/KeyMetadata'
        '401':
          $ref: '#/components/responses/Unauthorized'
      security:
      - bearerAuth: []
      x-codeSamples:
      - lang: JavaScript
        source: "import ContextDev from 'context.dev';\n\nconst client = new ContextDev({\n  apiKey: process.env['CONTEXT_DEV_API_KEY'],\
          \ // This is the default and can be omitted\n});\n\nconst batches = await client.batch.list();\n\nconsole.log(batches.data);"
      - lang: Python
        source: "import os\nfrom context.dev import ContextDev\n\nclient = ContextDev(\n    api_key=os.environ.get(\"CONTEXT_DEV_API_KEY\"\
          ),  # This is the default and can be omitted\n)\nbatches = client.batch.list()\nprint(batches.data)"
      - lang: Go
        source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/context-dot-dev/context-go-sdk\"\n\t\
          \"github.com/context-dot-dev/context-go-sdk/option\"\n)\n\nfunc main() {\n\tclient := contextdev.NewClient(\n\t\t\
          option.WithAPIKey(\"My API Key\"),\n\t)\n\tbatches, err := client.Batch.List(context.TODO(), contextdev.BatchListParams{})\n\
          \tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", batches.Data)\n}\n"
      - lang: Ruby
        source: 'require "context_dev"


          context_dev = ContextDev::Client.new(api_key: "My API Key")


          batches = context_dev.batch.list


          puts(batches)'
      - lang: PHP
        source: "<?php\n\nrequire_once dirname(__DIR__) . '/vendor/autoload.php';\n\nuse ContextDev\\Client;\nuse ContextDev\\\
          Core\\Exceptions\\APIException;\n\n$client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY') ?: 'My API Key');\n\
          \ntry {\n  $batches = $client->batch->list(\n    cursor: 'cursor',\n    limit: 1,\n    q: 'batch_1a2b',\n    searchType:\
          \ 'exact',\n    status: 'queued',\n    tags: 'docs,competitor',\n  );\n\n  var_dump($batches);\n} catch (APIException\
          \ $e) {\n  echo $e->getMessage();\n}"
      - lang: CLI
        source: "context-dev batch list \\\n  --api-key 'My API Key'"
  /batch/submit:
    post:
      tags:
      - Batch
      summary: Submit a batch
      description: 'Scrape 25K URLs or crawl large websites asynchronously. '
      operationId: submitBatch
      parameters:
      - schema:
          type: string
          maxLength: 200
          description: Any string unique to this submission. Retries with the same key return the original batch.
        required: false
        description: Any string unique to this submission. Retries with the same key return the original batch.
        name: Idempotency-Key
        in: header
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BatchSubmitRequest'
            examples:
              scrapeMarkdown:
                summary: Scrape URLs as Markdown
                value:
                  input:
                    type: scrape
                    data:
                      type: markdown
                      urls:
                      - url: https://example.com/products/anvil
                        itemId: sku-1
                        meta:
                          category: tools
                      - url: https://example.com/products/hammer
                        itemId: sku-2
                      options:
                        useMainContentOnly: true
              scrapeHtml:
                summary: Scrape URLs as HTML
                value:
                  input:
                    type: scrape
                    data:
                      type: html
                      urls:
                      - url: https://example.com/about
                      - url: https://example.com/pricing
              crawlStartUrlMarkdown:
                summary: Crawl from a URL as Markdown
                value:
                  input:
                    type: crawl
                    data:
                      type: markdown
                      source:
                        type: start_url
                        url: https://example.com/docs
                        controls:
                          maxUrls: 500
                          maxDepth: 3
                          followSubdomains: false
                          regex: ^https://example\.com/docs/
                      options:
                        includeLinks: true
              crawlStartUrlHtml:
                summary: Crawl from a URL as HTML
                value:
                  input:
                    type: crawl
                    data:
                      type: html
                      source:
                        type: start_url
                        url: https://example.com/blog
                        controls:
                          maxUrls: 100
              crawlSitemapMarkdown:
                summary: Crawl a sitemap as Markdown
                value:
                  input:
                    type: crawl
                    data:
                      type: markdown
                      source:
                        type: sitemap
                        domain: example.com
                        controls:
                          maxUrls: 500
                          regex: ^https://example\.com/docs/
              crawlSitemapHtml:
                summary: Crawl a sitemap as HTML
                value:
                  input:
                    type: crawl
                    data:
                      type: html
                      source:
                        type: sitemap
                        domain: example.com
                        controls:
                          maxUrls: 500
                          maxDepth: 0
      responses:
        '202':
          description: Batch accepted. Read progress and results from `GET /batch/{batch_id}`.
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/BatchAccepted'
                - type: object
                  properties:
                    key_metadata:
                      $ref: '#/components/schemas/KeyMetadata'
                      description: API key usage for this request.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: Concurrent batch limit reached (error_code BATCH_LIMIT_EXCEEDED).
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Idempotency-Key reused with a different body (error_code IDEMPOTENCY_KEY_CONFLICT).
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Batch input could not be staged or queued.
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
      - bearerAuth: []
      x-codeSamples:
      - lang: JavaScript
        source: "import ContextDev from 'context.dev';\n\nconst client = new ContextDev({\n  apiKey: process.env['CONTEXT_DEV_API_KEY'],\
          \ // This is the default and can be omitted\n});\n\nconst response = await client.batch.submit({\n  input: {\n \
          \   data: {\n      urls: [\n        {\n          url: 'https://example.com/products/anvil',\n          itemId: 'sku-1',\n\
          \          meta: { category: 'tools' },\n        },\n        { url: 'https://example.com/products/hammer', itemId:\
          \ 'sku-2' },\n      ],\n      options: { useMainContentOnly: true },\n    },\n  },\n});\n\nconsole.log(response.id);"
      - lang: Python
        source: "import os\nfrom context.dev import ContextDev\n\nclient = ContextDev(\n    api_key=os.environ.get(\"CONTEXT_DEV_API_KEY\"\
          ),  # This is the default and can be omitted\n)\nresponse = client.batch.submit(\n    input={\n        \"data\"\
          : {\n            \"urls\": [{\n                \"url\": \"https://example.com/products/anvil\",\n              \
          \  \"item_id\": \"sku-1\",\n                \"meta\": {\n                    \"category\": \"tools\"\n         \
          \       },\n            }, {\n                \"url\": \"https://example.com/products/hammer\",\n              \
          \  \"item_id\": \"sku-2\",\n            }],\n            \"options\": {\n                \"use_main_content_only\"\
          : True\n            },\n        }\n    },\n)\nprint(response.id)"
      - lang: Go
        source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/context-dot-dev/context-go-sdk\"\n\t\
          \"github.com/context-dot-dev/context-go-sdk/option\"\n)\n\nfunc main() {\n\tclient := contextdev.NewClient(\n\t\t\
          option.WithAPIKey(\"My API Key\"),\n\t)\n\tresponse, err := client.Batch.Submit(context.TODO(), contextdev.BatchSubmitParams{\n\
          \t\tInput: contextdev.BatchSubmitParamsInputUnion{\n\t\t\tOfScrape: &contextdev.BatchSubmitParamsInputScrape{\n\t\
          \t\t\tData: contextdev.BatchSubmitParamsInputScrapeDataUnion{\n\t\t\t\t\tOfMarkdown: &contextdev.BatchSubmitParamsInputScrapeDataMarkdown{\n\
          \t\t\t\t\t\tURLs: []contextdev.BatchSubmitParamsInputScrapeDataMarkdownURL{{\n\t\t\t\t\t\t\tURL:    \"https://example.com/products/anvil\"\
          ,\n\t\t\t\t\t\t\tItemID: contextdev.String(\"sku-1\"),\n\t\t\t\t\t\t\tMeta: map[string]any{\n\t\t\t\t\t\t\t\t\"\
          category\": \"tools\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tURL:    \"https://example.com/products/hammer\"\
          ,\n\t\t\t\t\t\t\tItemID: contextdev.String(\"sku-2\"),\n\t\t\t\t\t\t}},\n\t\t\t\t\t\tOptions: contextdev.BatchSubmitParamsInputScrapeDataMarkdownOptions{\n\
          \t\t\t\t\t\t\tUseMainContentOnly: contextdev.Bool(true),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\
          \t},\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", response.ID)\n}\n"
      - lang: Ruby
        source: "require \"context_dev\"\n\ncontext_dev = ContextDev::Client.new(api_key: \"My API Key\")\n\nresponse = context_dev.batch.submit(\n\
          \  input: {\n    data: {\n      format: :markdown,\n      urls: [{url: \"https://example.com/products/anvil\"},\
          \ {url: \"https://example.com/products/hammer\"}]\n    },\n    mode: :scrape\n  }\n)\n\nputs(response)"
      - lang: PHP
        source: "<?php\n\nrequire_once dirname(__DIR__) . '/vendor/autoload.php';\n\nuse ContextDev\\Client;\nuse ContextDev\\\
          Core\\Exceptions\\APIException;\n\n$client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY') ?: 'My API Key');\n\
          \ntry {\n  $response = $client->batch->submit(\n    input: [\n      'data' => [\n        'format' => 'markdown',\n\
          \        'urls' => [\n          [\n            'url' => 'https://example.com/products/anvil',\n            'itemID'\
          \ => 'sku-1',\n            'meta' => ['category' => 'bar'],\n          ],\n          [\n            'url' => 'https://example.com/products/hammer',\n\
          \            'itemID' => 'sku-2',\n            'meta' => ['foo' => 'bar'],\n          ],\n        ],\n        'options'\
          \ => [\n          'country' => 'de',\n          'excludeSelectors' => ['x'],\n          'includeHTML' => true,\n\
          \          'includeImages' => true,\n          'includeLinks' => true,\n          'includeSelectors' => ['x'],\n\
          \          'maxAgeMs' => 0,\n          'pdf' => [\n            'end' => 1, 'ocr' => true, 'shouldParse' => true,\
          \ 'start' => 1\n          ],\n          'settleAnimations' => true,\n          'shortenBase64Images' => true,\n\
          \          'useMainContentOnly' => true,\n          'waitForMs' => 0,\n        ],\n      ],\n      'mode' => 'scrape',\n\
          \    ],\n    tags: ['docs', 'competitor'],\n    webhookURL: 'webhookUrl',\n    idempotencyKey: 'Idempotency-Key',\n\
          \  );\n\n  var_dump($response);\n} catch (APIException $e) {\n  echo $e->getMessage();\n}"
      - lang: CLI
        source: "context-dev batch submit \\\n  --api-key 'My API Key' \\\n  --input '{data: {format: markdown, urls: [{url:\
          \ https://example.com/products/anvil}, {url: https://example.com/products/hammer}]}, mode: scrape}'"
  /batch/{batch_id}:
    delete:
      tags:
      - Batch
      summary: Delete a batch
      description: Permanently delete a finished batch and its stored results. Active batches must settle first.
      operationId: deleteBatch
      parameters:
      - schema:
          type: string
          example: batch_9f2c8a
          description: ID of the batch to retrieve or cancel.
        required: true
        description: ID of the batch to retrieve or cancel.
        name: batch_id
        in: path
      responses:
        '200':
          description: Batch and its stored results are permanently deleted.
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    description: ID of the deleted batch.
                  deleted:
                    type: boolean
                    description: Always true on success.
                  key_metadata:
                    $ref: '#/components/schemas/KeyMetadata'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: Batch is still active. Cancel it and let it settle before deleting.
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
      - bearerAuth: []
      x-codeSamples:
      - lang: JavaScript
        source: "import ContextDev from 'context.dev';\n\nconst client = new ContextDev({\n  apiKey: process.env['CONTEXT_DEV_API_KEY'],\
          \ // This is the default and can be omitted\n});\n\nconst batch = await client.batch.delete('batch_9f2c8a');\n\n\
          console.log(batch.id);"
      - lang: Python
        source: "import os\nfrom context.dev import ContextDev\n\nclient = ContextDev(\n    api_key=os.environ.get(\"CONTEXT_DEV_API_KEY\"\
          ),  # This is the default and can be omitted\n)\nbatch = client.batch.delete(\n    \"batch_9f2c8a\",\n)\nprint(batch.id)"
      - lang: Go
        source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/context-dot-dev/context-go-sdk\"\n\t\
          \"github.com/context-dot-dev/context-go-sdk/option\"\n)\n\nfunc main() {\n\tclient := contextdev.NewClient(\n\t\t\
          option.WithAPIKey(\"My API Key\"),\n\t)\n\tbatch, err := client.Batch.Delete(context.TODO(), \"batch_9f2c8a\")\n\
          \tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", batch.ID)\n}\n"
      - lang: Ruby
        source: 'require "context_dev"


          context_dev = ContextDev::Client.new(api_key: "My API Key")


          batch = context_dev.batch.delete("batch_9f2c8a")


          puts(batch)'
      - lang: PHP
        source: "<?php\n\nrequire_once dirname(__DIR__) . '/vendor/autoload.php';\n\nuse ContextDev\\Client;\nuse ContextDev\\\
          Core\\Exceptions\\APIException;\n\n$client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY') ?: 'My API Key');\n\
          \ntry {\n  $batch = $client->batch->delete('batch_9f2c8a');\n\n  var_dump($batch);\n} catch (APIException $e) {\n\
          \  echo $e->getMessage();\n}"
      - lang: CLI
        source: "context-dev batch delete \\\n  --api-key 'My API Key' \\\n  --batch-id batch_9f2c8a"
    get:
      tags:
      - Batch
      summary: Get a batch
      description: Check progress, and get download links once the batch finishes.
      operationId: getBatch
      parameters:
      - schema:
          type: string
          example: batch_9f2c8a
          description: ID of the batch to retrieve or cancel.
        required: true
        description: ID of the batch to retrieve or cancel.
        name: batch_id
        in: path
      responses:
        '200':
          description: Current state of the batch, with download links once it has finished.
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/Batch'
                - type: object
                  properties:
                    key_metadata:
                      $ref: '#/components/schemas/KeyMetadata'
                      description: API key usage for this request.
                - $ref: '#/components/schemas/BatchDetail'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
      security:
      - bearerAuth: []
      x-codeSamples:
      - lang: JavaScript
        source: "import ContextDev from 'context.dev';\n\nconst client = new ContextDev({\n  apiKey: process.env['CONTEXT_DEV_API_KEY'],\
          \ // This is the default and can be omitted\n});\n\nconst batch = await client.batch.retrieve('batch_9f2c8a');\n\
          \nconsole.log(batch.id);"
      - lang: Python
        source: "import os\nfrom context.dev import ContextDev\n\nclient = ContextDev(\n    api_key=os.environ.get(\"CONTEXT_DEV_API_KEY\"\
          ),  # This is the default and can be omitted\n)\nbatch = client.batch.retrieve(\n    \"batch_9f2c8a\",\n)\nprint(batch.id)"
      - lang: Go
        source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/context-dot-dev/context-go-sdk\"\n\t\
          \"github.com/context-dot-dev/context-go-sdk/option\"\n)\n\nfunc main() {\n\tclient := contextdev.NewClient(\n\t\t\
          option.WithAPIKey(\"My API Key\"),\n\t)\n\tbatch, err := client.Batch.Get(context.TODO(), \"batch_9f2c8a\")\n\t\
          if err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", batch.ID)\n}\n"
      - lang: Ruby
        source: 'require "context_dev"


          context_dev = ContextDev::Client.new(api_key: "My API Key")


          batch = context_dev.batch.retrieve("batch_9f2c8a")


          puts(batch)'
      - lang: PHP
        source: "<?php\n\nrequire_once dirname(__DIR__) . '/vendor/autoload.php';\n\nuse ContextDev\\Client;\nuse ContextDev\\\
          Core\\Exceptions\\APIException;\n\n$client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY') ?: 'My API Key');\n\
          \ntry {\n  $batch = $client->batch->retrieve('batch_9f2c8a');\n\n  var_dump($batch);\n} catch (APIException $e)\
          \ {\n  echo $e->getMessage();\n}"
      - lang: CLI
        source: "context-dev batch retrieve \\\n  --api-key 'My API Key' \\\n  --batch-id batch_9f2c8a"
  /batch/{batch_id}/cancel:
    post:
      tags:
      - Batch
      summary: Cancel a batch
      description: Stop a batch from starting new pages. In-progress pages finish, and unused credits are refunded.
      operationId: cancelBatch
      parameters:
      - schema:
          type: string
          example: batch_9f2c8a
          description: ID of the batch to retrieve or cancel.
        required: true
        description: ID of the batch to retrieve or cancel.
        name: batch_id
        in: path
      responses:
        '202':
          description: Cancellation started. Poll `GET /batch/{batch_id}` until the batch settles.
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/BatchCancelling'
                - type: object
                  properties:
                    key_metadata:
                      $ref: '#/components/schemas/KeyMetadata'
                      description: API key usage for this request.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: Batch already reached a terminal state, so there is nothing to cancel.
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
      - bearerAuth: []
      x-codeSamples:
      - lang: JavaScript
        source: "import ContextDev from 'context.dev';\n\nconst client = new ContextDev({\n  apiKey: process.env['CONTEXT_DEV_API_KEY'],\
          \ // This is the default and can be omitted\n});\n\nconst response = await client.batch.cancel('batch_9f2c8a');\n\
          \nconsole.log(response.id);"
      - lang: Python
        source: "import os\nfrom context.dev import ContextDev\n\nclient = ContextDev(\n    api_key=os.environ.get(\"CONTEXT_DEV_API_KEY\"\
          ),  # This is the default and can be omitted\n)\nresponse = client.batch.cancel(\n    \"batch_9f2c8a\",\n)\nprint(response.id)"
      - lang: Go
        source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/context-dot-dev/context-go-sdk\"\n\t\
          \"github.com/context-dot-dev/context-go-sdk/option\"\n)\n\nfunc main() {\n\tclient := contextdev.NewClient(\n\t\t\
          option.WithAPIKey(\"My API Key\"),\n\t)\n\tresponse, err := client.Batch.Cancel(context.TODO(), \"batch_9f2c8a\"\
          )\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", response.ID)\n}\n"
      - lang: Ruby
        source: 'require "context_dev"


          context_dev = ContextDev::Client.new(api_key: "My API Key")


          response = context_dev.batch.cancel("batch_9f2c8a")


          puts(response)'
      - lang: PHP
        source: "<?php\n\nrequire_once dirname(__DIR__) . '/vendor/autoload.php';\n\nuse ContextDev\\Client;\nuse ContextDev\\\
          Core\\Exceptions\\APIException;\n\n$client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY') ?: 'My API Key');\n\
          \ntry {\n  $response = $client->batch->cancel('batch_9f2c8a');\n\n  var_dump($response);\n} catch (APIException\
          \ $e) {\n  echo $e->getMessage();\n}"
      - lang: CLI
        source: "context-dev batch cancel \\\n  --api-key 'My API Key' \\\n  --batch-id batch_9f2c8a"
  /batch/{batch_id}/results:
    get:
      tags:
      - Batch
      summary: Get batch results
      description: Page through a finished batch's results as JSON instead of downloading the NDJSON files.
      operationId: getBatchResults
      parameters:
      - schema:
          type: string
          example: batch_9f2c8a
          description: ID of the batch to retrieve or cancel.
        required: true
        description: ID of the batch to retrieve or cancel.
        name: batch_id
        in: path
      - schema:
          type: integer
          minimum: 1
          maximum: 100
          description: Records per page. Defaults to 25. A page can close early so its payload stays under ~8 MB; rely on
            next_cursor rather than counting records.
        required: false
        description: Records per page. Defaults to 25. A page can close early so its payload stays under ~8 MB; rely on next_cursor
          rather than counting records.
        name: limit
        in: query
      - schema:
          type: string
          description: next_cursor from the previous page.
        required: false
        description: next_cursor from the previous page.
        name: cursor
        in: query
      responses:
        '200':
          description: One page of result records. Keep paging with `next_cursor` while `has_more` is true.
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/BatchResultRecord'
                    description: Result records on this page.
                  has_more:
                    type: boolean
                    description: Whether another page is available.
                  next_cursor:
                    type: string
                    nullable: true
                    description: Cursor for the next page.
                  key_metadata:
                    $ref: '#/components/schemas/KeyMetadata'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: Batch has not finished yet (error_code BATCH_NOT_COMPLETED).
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
      - bearerAuth: []
      x-codeSamples:
      - lang: JavaScript
        source: "import ContextDev from 'context.dev';\n\nconst client = new ContextDev({\n  apiKey: process.env['CONTEXT_DEV_API_KEY'],\
          \ // This is the default and can be omitted\n});\n\nconst response = await client.batch.getResults('batch_9f2c8a');\n\
          \nconsole.log(response.data);"
      - lang: Python
        source: "import os\nfrom context.dev import ContextDev\n\nclient = ContextDev(\n    api_key=os.environ.get(\"CONTEXT_DEV_API_KEY\"\
          ),  # This is the default and can be omitted\n)\nresponse = client.batch.get_results(\n    batch_id=\"batch_9f2c8a\"\
          ,\n)\nprint(response.data)"
      - lang: Go
        source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/context-dot-dev/context-go-sdk\"\n\t\
          \"github.com/context-dot-dev/context-go-sdk/option\"\n)\n\nfu

# --- truncated at 32 KB (100 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/contextdev/refs/heads/main/openapi/contextdev-batch-api-openapi.yml