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

# Run a slow service as a background job

> For services whose provider takes minutes to respond: `getEmail`,
`getPhoneNumber`, `webResearch`, `getLinkedInUserComments`,
`getLinkedInUserReactions`. Retriever responds immediately with an id,
does the work, and keeps the result until you fetch it, even if your
client disconnected in the meantime.

Any other service is rejected with `service_not_async`: call it directly
on `POST /services/{serviceName}`; it responds in a few seconds.

`Idempotency-Key` is recommended. Replaying the same key with the same
body returns the first job and `200` instead of `202`, so a retried
request never pays for two executions.




## OpenAPI

````yaml /openapi.yaml post /v1/services/jobs
openapi: 3.1.0
info:
  title: Retriever Public API
  version: 1.0.0
  description: >
    Retriever public API: start the prospecting agent (runs), read and export

    tables, import data, sync exclusion lists, run structured research (Go),

    and call atomic services.


    **Model Context Protocol (MCP)**: the same account and credits are available

    through the hosted MCP server (`POST /mcp`, Streamable HTTP). See the MCP

    guide in this documentation (Model Context Protocol navigation). Primary

    tools: `service_discover`, `service_execute`, `retriever_build_list_start`,

    `table_*`, `sequence_*`, `inbox_*`.


    **Authentication**: `Authorization: Bearer ret_live_…`. Create the key in
    the

    app: Settings → **API keys** → **Create API key**. The key grants access to

    resources in the key owner's organization.


    **Errors**: every HTTP error has the shape

    `{ "error": { "code": "…", "message": "…", "details": … } }`.

    Branch your code on `error.code` (stable), never on `message`.


    **Rate limits**: key-authenticated responses include

    `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` (seconds).

    A `429` response also includes `Retry-After` (seconds).


    API error messages are in English.
  contact:
    name: Retriever
servers:
  - url: https://api.retriever.run
    description: Production
  - url: http://localhost:4320
    description: Local app-server
security:
  - bearerAuth: []
tags:
  - name: Runs
    description: Prospecting agent « prompt in, table out ». Asynchronous.
  - name: Tables
    description: Read live tables in a workspace.
  - name: Workspaces
    description: Create workspaces and import tables.
  - name: Exclusions
    description: Company and people lists to never source.
  - name: Go
    description: Autonomous web research and structured extraction.
  - name: Services
    description: Atomic services (search, scraping, email…).
  - name: Credits
    description: Credit balance.
paths:
  /v1/services/jobs:
    post:
      tags:
        - Services
      summary: Run a slow service as a background job
      description: |
        For services whose provider takes minutes to respond: `getEmail`,
        `getPhoneNumber`, `webResearch`, `getLinkedInUserComments`,
        `getLinkedInUserReactions`. Retriever responds immediately with an id,
        does the work, and keeps the result until you fetch it, even if your
        client disconnected in the meantime.

        Any other service is rejected with `service_not_async`: call it directly
        on `POST /services/{serviceName}`; it responds in a few seconds.

        `Idempotency-Key` is recommended. Replaying the same key with the same
        body returns the first job and `200` instead of `202`, so a retried
        request never pays for two executions.
      operationId: createServiceJob
      parameters:
        - name: Idempotency-Key
          in: header
          required: false
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - service
                - input
              properties:
                service:
                  type: string
                  example: getEmail
                input:
                  type: object
                  description: >-
                    Input matching the schema from `GET
                    /services/{serviceName}`.
      responses:
        '200':
          description: 'Replay of an already-used `Idempotency-Key`: the existing job.'
          content:
            application/json:
              schema:
                type: object
        '202':
          description: Job accepted.
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  job_id:
                    type: string
                    example: svcjob_9f2c4b1e8a7d6c5f
                  service:
                    type: string
                  status:
                    type: string
                    enum:
                      - queued
                  poll_url:
                    type: string
                  created_at:
                    type: string
                    format: date-time
        '400':
          description: >-
            `invalid_request` (non-conforming input) or `service_not_async`
            (ineligible service; the message lists eligible ones).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: '`service_not_found`: unknown or non-public service.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: '`idempotency_conflict`: this key was used with a different body.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '503':
          description: '`not_available`: jobs are not enabled on this deployment.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Stable code; use in your application.
            message:
              type: string
              description: Human-readable explanation. May change.
            details:
              description: Optional details (e.g. list of invalid fields).
  responses:
    Unauthorized:
      description: >-
        `not_authenticated`: missing header, malformed (expected `Bearer
        <key>`), revoked or unknown key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: not_authenticated
              message: A valid API key is required.
    TooManyRequests:
      description: '`rate_limited`: wait `Retry-After` seconds, then retry.'
      headers:
        Retry-After:
          schema:
            type: integer
        RateLimit-Limit:
          $ref: '#/components/headers/RateLimit-Limit'
        RateLimit-Remaining:
          $ref: '#/components/headers/RateLimit-Remaining'
        RateLimit-Reset:
          $ref: '#/components/headers/RateLimit-Reset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: rate_limited
              message: Rate limit exceeded. Retry later.
  headers:
    RateLimit-Limit:
      schema:
        type: integer
      description: Window budget.
    RateLimit-Remaining:
      schema:
        type: integer
      description: Remaining requests.
    RateLimit-Reset:
      schema:
        type: integer
      description: Seconds until reset.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: API key `ret_live_…` created in Settings → API keys.

````