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

# Start background jobs

> Run your skills and workflows in the background, one at a time or several as a batch.

Give `items`, 1 to 6 things to run. Each is `kind: skill` with `skill` (its id or slug) or `kind: workflow` with `workflow_id`, plus optional `inputs`, `max_results` (skills, 1–500), and a short `label`. Two or more items start a [batch](/concepts/background-jobs#batches); `label` at the top names it.

The answer comes at once (`202`): `jobs` holds each job that started, and `batch` the batch when there are two or more. Nothing calls you back: poll [Get a background job](/api-reference/jobs/get) for each job, or for the batch, which ends when they all have.

An item that cannot start (no such skill, inputs that do not fit, not enough credits) is listed in `refused` with the reason, and the others still start. Research helpers start only from a chat in the app, not here.

Starting twice runs twice, so send an `Idempotency-Key` to make a retry safe. See [Idempotency](/api-reference/pagination-and-idempotency#idempotency).

| Status | Why |
| - | - |
| `403` | The key lacks `jobs:write`, `skills:invoke` or `workflows:invoke` for what you start, or is limited to other skills or workflows. |
| `422` | A field is wrong (`param` names it), more than 6 items, or none of the items could start (`detail` lists why for each). |

MCP tool: `start_jobs`.


## OpenAPI

````yaml POST /v1/jobs
openapi: 3.1.0
info:
  title: Valendata REST API
  version: 1.0.0
  description: >-
    Create, run, schedule, and improve skills and workflows over JSON and HTTPS.
    Every route is under `/v1`; changes inside v1 are additive only (new routes,
    new optional parameters, new response fields). A route that will go away is
    marked `deprecated` here and answers with `Deprecation`, `Sunset` and a
    `Link` to its replacement for at least six months before it is removed.
    Errors, limits, pagination and idempotency:
    https://docs.valendata.com/api-reference/errors.
  license:
    name: Proprietary
    url: https://www.valendata.com/terms-and-conditions
servers:
  - url: https://api.valendata.com
    description: Production
security:
  - ApiKeyAuth: []
  - ApiKeyHeader: []
tags:
  - name: Skills
    description: List, create, read, update, and delete skills.
  - name: Marketplace
    description: Find a skill by the task, with its price per run and track record.
  - name: Runs
    description: Run skills and workflows, read any run, and cancel one.
  - name: Skill versions
    description: List, compare, restore, and pin a skill's versions.
  - name: Improvements
    description: >-
      Fix a skill, add fields, or re-learn its detail steps, and read its change
      history.
  - name: Schedules
    description: Run a skill or workflow on a fixed cadence.
  - name: Workflows
    description: List, create, read, update, and delete workflows.
  - name: Logins
    description: Saved website logins a skill can sign in with.
  - name: Connected apps
    description: >-
      Your own accounts (Gmail, Calendar, Slack …): connect them, list their
      tools, and run one.
  - name: Follow-ups
    description: >-
      Wait for something to arrive (a code, a link, a file, a message) or check
      back later, and read what came.
  - name: Jobs
    description: >-
      What your agents started to run in the background (skill runs, workflow
      runs, research), what came back, and stopping it.
  - name: Notes
    description: >-
      The notes on your Notes page: list and search them, read one, write,
      change, and delete them.
  - name: Account and usage
    description: Your plan, credit balance, and usage.
  - name: Webhooks
    description: The secret that signs webhook deliveries.
paths:
  /v1/jobs:
    post:
      tags:
        - Jobs
      summary: Start background jobs
      description: >-
        Start your skills and workflows to run in the background, each as a job
        with its own status. One item starts one job; two or more start a batch
        (`batch`) that ends when they all have. The answer comes at once (202)
        with the jobs; poll each with `GET /v1/jobs/{job_id}` (or the batch). An
        item that cannot start is listed in `refused` and the others still
        start; when none can, 422. Research helpers start from a chat, not the
        API. Needs `jobs:write`, plus `skills:invoke` / `workflows:invoke` for
        what you start.
      operationId: start_jobs
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StartJobs'
      responses:
        '202':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StartedJobs'
          headers:
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Unprocessable'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - ApiKeyAuth: []
        - ApiKeyHeader: []
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      schema:
        type: string
        minLength: 1
        maxLength: 255
      description: >-
        Any unique string (such as your order id). Resending the same request
        with the same key within 24 hours returns the first answer (with
        `Idempotent-Replayed: true`) and does nothing twice; the same key with a
        different request is a 422 `idempotency_key_reused`.
      example: order-1234
  schemas:
    StartJobs:
      properties:
        items:
          items:
            $ref: '#/components/schemas/StartItem'
          type: array
          maxItems: 6
          minItems: 1
          title: Items
          description: 1 to 6 things to run. Two or more start a batch.
        label:
          anyOf:
            - type: string
              maxLength: 200
            - type: 'null'
          title: Label
          description: 'Two or more items: the batch''s name.'
      type: object
      required:
        - items
      title: StartJobs
    StartedJobs:
      properties:
        batch:
          anyOf:
            - $ref: '#/components/schemas/Job'
            - type: 'null'
          description: >-
            The batch grouping them, when two or more were started: it ends when
            they all have.
        jobs:
          items:
            $ref: '#/components/schemas/Job'
          type: array
          title: Jobs
          description: The jobs that started, each running on its own.
        refused:
          items:
            type: string
          type: array
          title: Refused
          description: Each item that could not start, and why.
      type: object
      required:
        - jobs
      title: StartedJobs
    StartItem:
      properties:
        kind:
          type: string
          enum:
            - skill
            - workflow
          title: Kind
          description: >-
            What to run: one of your skills or one of your workflows. (Research
            helpers start from a chat.)
        skill:
          anyOf:
            - type: string
              maxLength: 255
            - type: 'null'
          title: Skill
          description: 'kind `skill`: the skill''s id or slug.'
        workflow_id:
          anyOf:
            - type: string
              maxLength: 255
            - type: 'null'
          title: Workflow Id
          description: 'kind `workflow`: the workflow''s id.'
        inputs:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Inputs
          description: Its inputs, by name.
        max_results:
          anyOf:
            - type: integer
              maximum: 500
              minimum: 1
            - type: 'null'
          title: Max Results
          description: 'kind `skill`: at most this many rows.'
        label:
          anyOf:
            - type: string
              maxLength: 200
            - type: 'null'
          title: Label
          description: A short name for it, e.g. 'eBay search'.
      type: object
      required:
        - kind
      title: StartItem
    Job:
      properties:
        id:
          type: string
          title: Id
        origin_kind:
          type: string
          enum:
            - session
            - igris
            - brain
            - api
          title: Origin Kind
          description: >-
            Who started it: `session` (a chat session's agent), `igris` (the
            assistant), `brain` (a workflow's Brain, which may report results)
            or `api`.
        origin_id:
          type: string
          title: Origin Id
          description: >-
            The session or workflow that started it; empty for the assistant and
            the API.
          default: ''
        group_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Group Id
          description: The batch job it belongs to, when several were started together.
        kind:
          type: string
          enum:
            - skill
            - workflow
            - research
            - batch
          title: Kind
          description: >-
            What it runs: a `skill`, a `workflow`, a `research` helper, or a
            `batch` grouping jobs started together.
        label:
          type: string
          title: Label
          description: What it is, in the words it was started with, e.g. 'eBay search'.
          default: ''
        target_id:
          type: string
          title: Target Id
          description: The skill or workflow it runs.
          default: ''
        run_ref:
          anyOf:
            - type: string
            - type: 'null'
          title: Run Ref
          description: >-
            The run it drives (GET /v1/runs/{run_id} for a skill or workflow);
            null until it has started.
        status:
          type: string
          enum:
            - queued
            - running
            - completed
            - failed
            - cancelled
          title: Status
          description: '`queued`, `running`, then one of `completed`, `failed`, `cancelled`.'
        summary:
          anyOf:
            - type: string
            - type: 'null'
          title: Summary
          description: One plain line of what came back, once it ended.
        result:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Result
          description: >-
            A small result: `count` and a `preview` of the first rows. The run
            has the rest.
        error:
          anyOf:
            - type: string
            - type: 'null'
          title: Error
          description: Why it failed.
        cancel_requested:
          type: boolean
          title: Cancel Requested
          description: A stop was asked for; it ends `cancelled` soon.
          default: false
        attempts:
          type: integer
          title: Attempts
          description: How many times its run was started.
          default: 0
        created_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Created At
        started_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Started At
        ended_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Ended At
        link:
          type: string
          title: Link
          description: >-
            The path of the page in the Valendata app that shows its run (e.g.
            /skills/runs/run_…); empty until it has started.
          default: ''
      type: object
      required:
        - id
        - origin_kind
        - kind
        - status
      title: Job
    Error:
      type: object
      required:
        - detail
        - code
        - type
        - request_id
      properties:
        detail:
          description: What went wrong. A string, or an object for errors with more to say.
          oneOf:
            - type: string
            - additionalProperties: true
              type: object
        code:
          type: string
          description: >-
            Stable machine-readable code. Known values: `bad_request`,
            `invalid_json`, `invalid_cursor`, `invalid_idempotency_key`,
            `unauthorized`, `payment_required`, `permission_denied`,
            `not_found`, `method_not_allowed`, `conflict`, `app_not_connected`,
            `idempotency_key_in_use`, `idempotent_replay_unavailable`,
            `payload_too_large`, `unsupported_media_type`, `validation_error`,
            `idempotency_key_reused`, `rate_limited`, `internal_error`,
            `upstream_error`, `service_unavailable`.
          example: not_found
        type:
          type: string
          enum:
            - invalid_request_error
            - authentication_error
            - billing_error
            - permission_error
            - conflict_error
            - idempotency_error
            - rate_limit_error
            - api_error
          description: The broad category of the error.
        request_id:
          type: string
          description: Also in the `X-Request-ID` header.
          example: 3f9a1c2b7d4e
        param:
          type: string
          description: >-
            The field at fault, on validation errors (dotted path, e.g.
            `inputs.city`).
        errors:
          type: array
          items:
            additionalProperties: true
            type: object
          description: Every validation problem, on a 422 from request validation.
  headers:
    X-Request-ID:
      description: >-
        This request's id (yours, if you sent a valid `X-Request-ID`). Quote it
        to support.
      schema:
        type: string
    X-RateLimit-Limit:
      description: Requests a minute this API key may make.
      schema:
        type: integer
    X-RateLimit-Remaining:
      description: Requests left in the current minute.
      schema:
        type: integer
    X-RateLimit-Reset:
      description: Unix time (seconds) the current window ends.
      schema:
        type: integer
    Idempotent-Replayed:
      description: >-
        `true` when this is the stored answer to an earlier request with the
        same Idempotency-Key.
      schema:
        type: string
    Retry-After:
      description: Seconds to wait before retrying.
      schema:
        type: integer
  responses:
    BadRequest:
      description: >-
        The request is malformed: the body is not JSON, the cursor or
        Idempotency-Key is not valid.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: >-
              The request is malformed: the body is not JSON, the cursor or
              Idempotency-Key is not valid.
            code: invalid_json
            type: invalid_request_error
            request_id: 3f9a1c2b7d4e
    Unauthorized:
      description: The API key is missing, malformed, revoked, or expired.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: The API key is missing, malformed, revoked, or expired.
            code: unauthorized
            type: authentication_error
            request_id: 3f9a1c2b7d4e
    Forbidden:
      description: >-
        The key lacks a scope, is limited to other skills or workflows, or you
        may not do this.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: >-
              The key lacks a scope, is limited to other skills or workflows, or
              you may not do this.
            code: permission_denied
            type: permission_error
            request_id: 3f9a1c2b7d4e
    Conflict:
      description: >-
        A conflict with the current state, or a request with this
        Idempotency-Key is still running.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
        Retry-After:
          $ref: '#/components/headers/Retry-After'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: >-
              A conflict with the current state, or a request with this
              Idempotency-Key is still running.
            code: conflict
            type: conflict_error
            request_id: 3f9a1c2b7d4e
    Unprocessable:
      description: >-
        A field is invalid (`param` names it), or the Idempotency-Key was used
        with a different request.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: 'Invalid request — name: Field required'
            code: validation_error
            type: invalid_request_error
            request_id: 3f9a1c2b7d4e
            param: name
            errors:
              - type: missing
                loc:
                  - body
                  - name
                msg: Field required
    RateLimited:
      description: >-
        Too many requests for this key, or too many runs in progress. Wait
        `Retry-After` seconds.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
        Retry-After:
          $ref: '#/components/headers/Retry-After'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: >-
              Too many requests for this key, or too many runs in progress. Wait
              `Retry-After` seconds.
            code: rate_limited
            type: rate_limit_error
            request_id: 3f9a1c2b7d4e
    InternalError:
      description: >-
        Something broke on our side. Retry; runs that fail on our side are
        refunded.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-Request-ID:
          $ref: '#/components/headers/X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: >-
              Something broke on our side. Retry; runs that fail on our side are
              refunded.
            code: internal_error
            type: api_error
            request_id: 3f9a1c2b7d4e
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: vd_sk_...
      description: >-
        API key with the `vd_sk_` prefix, as `Authorization: Bearer vd_sk_...`.
        Create keys in Settings → API Keys.
    ApiKeyHeader:
      type: apiKey
      in: header
      name: x-api-key
      description: The same API key in the `x-api-key` header.

````

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