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

# Create measurement job

> One async ingest resource. `source:"current"` captures present counts via the snapshot pipeline. `source:"historical"` enqueues each resolved recording for Songstats deep backfill ranked by all-time streams (idempotent — songs already carrying `songstats` history are skipped; no track is fetched twice). Provide exactly one of `catalog_id` / `album_ids` / `isrcs` in `scope`. The returned `id` is a snapshot id you can pass to [Create catalog](/api-reference/songs/catalogs-create) to materialize the measured tracks into an account-owned catalog.



## OpenAPI

````yaml api-reference/openapi/research.json POST /api/research/measurement-jobs
openapi: 3.1.0
info:
  title: Recoup API - Research
  description: >-
    API documentation for the Recoup platform - an AI agent platform for the
    music industry
  license:
    name: MIT
  version: 1.0.0
servers:
  - url: https://api.recoupable.dev
security: []
paths:
  /api/research/measurement-jobs:
    post:
      summary: Create a measurement job
      description: >-
        One async ingest resource. `source:"current"` captures present counts
        via the snapshot pipeline. `source:"historical"` enqueues each resolved
        recording for Songstats deep backfill ranked by all-time streams
        (idempotent — songs already carrying `songstats` history are skipped; no
        track is fetched twice). Provide exactly one of `catalog_id` /
        `album_ids` / `isrcs` in `scope`. The returned `id` is a snapshot id you
        can pass to [Create catalog](/api-reference/songs/catalogs-create) to
        materialize the measured tracks into an account-owned catalog.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ResearchMeasurementJobRequest'
      responses:
        '202':
          description: Job accepted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResearchMeasurementJobResponse'
        '400':
          description: >-
            Validation error — provide a `source` and exactly one of
            `scope.catalog_id`, `scope.album_ids`, `scope.isrcs`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResearchErrorResponse'
        '401':
          description: Authentication failed — invalid or missing API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResearchErrorResponse'
        '429':
          description: Per-organization monthly cap reached (current jobs).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResearchErrorResponse'
components:
  schemas:
    ResearchMeasurementJobRequest:
      type: object
      required:
        - scope
        - source
      properties:
        scope:
          $ref: '#/components/schemas/ResearchMeasurementJobScope'
        source:
          type: string
          enum:
            - current
            - historical
          description: >-
            `current` = capture present counts (Apify snapshot). `historical` =
            enqueue Songstats deep backfill.
        platforms:
          type: array
          items:
            type: string
          default:
            - spotify
          example:
            - spotify
    ResearchMeasurementJobResponse:
      type: object
      description: >-
        For `current` jobs, `id` is pollable. For `historical` jobs,
        `enqueued`/`skipped` summarize the backfill enqueue (the queue drains
        via the daily worker).
      properties:
        status:
          type: string
          example: success
        source:
          type: string
          example: historical
        id:
          type: string
          format: uuid
          nullable: true
          description: Job id for `current` jobs; null for `historical`.
        state:
          type: string
          enum:
            - queued
          nullable: true
          example: queued
        enqueued:
          type: integer
          nullable: true
          description: '`historical`: recordings enqueued for backfill.'
          example: 842
        skipped:
          type: integer
          nullable: true
          description: '`historical`: recordings already backfilled (skipped).'
          example: 3
        album_count:
          type: integer
          nullable: true
          description: '`current`: albums the job will capture.'
        estimated_cost_usd:
          type: number
          nullable: true
          description: '`current`: scraper cost estimate before spend.'
    ResearchErrorResponse:
      type: object
      required:
        - status
        - error
      description: >-
        Error response returned by all research endpoints for validation
        failures (400) and authentication errors (401).
      properties:
        status:
          type: string
          enum:
            - error
          example: error
        error:
          type: string
          description: Human-readable error message describing what went wrong.
          example: 'Missing required parameter: artist'
    ResearchMeasurementJobScope:
      type: object
      description: Provide exactly one of `catalog_id`, `album_ids`, or `isrcs`.
      properties:
        catalog_id:
          type: string
          format: uuid
        album_ids:
          type: array
          items:
            type: string
        isrcs:
          type: array
          items:
            type: string

````