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

# Convert every quote matching a target into a job

> Requires ALL of the scopes quotes.write, jobs.write.

Required scopes: `quotes.write`, `jobs.write`.


## OpenAPI

````yaml POST /v1/quotes/bulk/convert-to-jobs
openapi: 3.1.0
info:
  title: PRINTOOLS API
  version: 1.0.0
  description: >-
    The PRINTOOLS public REST API. This document is generated from the live
    route table and service GraphQL SDL; do not edit it by hand.


    Every 2xx response has {status, message, data}. Every non-2xx response has
    {error, message, status: false}.


    Tenant credential: send X-API-Key only. It is bound to one shop.
    X-PrintTools-Organization-Id is optional for that credential and, if sent,
    must match its shop.


    Partner credential: send X-API-Key, X-API-Secret, Authorization: Bearer
    <Cognito access token>, and X-PrintTools-Organization-Id. The OAuth flow is
    documented at https://app.printools.io/api/index.html#partner-auth.


    Read live limits from GET /v1/reference/limits. Field shapes are projected
    from operation declarations; local endpoints have explicit handler-derived
    schemas.
servers:
  - url: https://api.printools.io
    description: Production
security: []
externalDocs:
  description: Getting started, OAuth and webhook guidance
  url: https://app.printools.io/api/index.html
paths:
  /v1/quotes/bulk/convert-to-jobs:
    post:
      tags:
        - quotes
      summary: Convert every quote matching a target into a job.
      description: Requires ALL of the scopes quotes.write, jobs.write.
      operationId: post_v1_quotes_bulk_convert_to_jobs
      parameters:
        - name: X-PrintTools-Organization-Id
          in: header
          required: false
          schema:
            type: string
            format: uuid
          description: >-
            Tenant credential: optional and, when sent, must equal the shop
            bound to the key. Partner credential: required; it selects an
            organisation the user previously authorised.
        - name: Idempotency-Key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 200
          description: >-
            Optional client-generated key for write retries. Reusing it with a
            different request returns 409; a replay includes
            Idempotency-Replayed: true.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                target:
                  $ref: '#/components/schemas/Input_BulkTargetInput'
              required:
                - target
            examples:
              example:
                summary: Replace example values with a request for your shop.
                value:
                  target:
                    ids:
                      - 11111111-2222-3333-4444-555555555555
                    filters:
                      - field: example
                        op: example
                        value: example
                        values:
                          - example
                        from: example
                        to: example
                    search: example
                    excludeIds:
                      - 11111111-2222-3333-4444-555555555555
      responses:
        '201':
          description: Successful response.
          headers:
            Idempotency-Replayed:
              description: >-
                Present and true when this response was replayed from a prior
                Idempotency-Key request.
              schema:
                type: string
                enum:
                  - 'true'
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Success'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/Output_BulkResult'
        '400':
          description: >-
            Validation or request-shape error. Correct the request before
            retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Credential authentication failed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          headers:
            WWW-Authenticate:
              schema:
                type: string
                example: ApiKey
        '403':
          description: >-
            The credential lacks a required scope, or its actor lacks
            permission.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: The resource or endpoint was not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: >-
            Conflict, including idempotency-key reuse or an in-flight idempotent
            request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '413':
          description: The JSON request body exceeds the published size limit.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limited. Retry after the returned delay.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          headers:
            Retry-After:
              description: Whole seconds to wait.
              schema:
                type: integer
                minimum: 0
        '500':
          description: An unexpected server error. A retry can be appropriate.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - tenantApiKey: []
        - partnerApiKey: []
          partnerApiSecret: []
          partnerBearer: []
      x-codeSamples:
        - lang: curl
          label: Tenant credential
          source: >-
            curl --request POST
            'https://api.printools.io/v1/quotes/bulk/convert-to-jobs' \
              --header 'X-API-Key: $PRINTOOLS_API_KEY' \
              --header 'Content-Type: application/json' \
              --data '{"target":{"ids":["11111111-2222-3333-4444-555555555555"],"filters":[{"field":"example","op":"example","value":"example","values":["example"],"from":"example","to":"example"}],"search":"example","excludeIds":["11111111-2222-3333-4444-555555555555"]}}'
components:
  schemas:
    Input_BulkTargetInput:
      type: object
      description: >-
        A bulk selection, as it travels to a bulk mutation. Exactly ONE branch
        is

        populated: `ids` for hand-picked rows (the common case), or the filter
        branch

        (`filters` / `search` / `excludeIds`) for "select all matching".
        Supplying both

        is a validation error rather than a silent reconciliation.


        The filter branch reuses the SAME `ListFilterInput` the list query was
        issued

        with, so bulk never grows a second filter language, and `excludeIds`
        carries the

        rows the operator un-ticked while select-all-matching was on.


        The filter branch is RE-EVALUATED AT EXECUTION TIME: a row created
        between the

        operator ticking select-all-matching and confirming IS included. That is
        the

        honest meaning of "everything matching this filter", and it is why a
        confirm

        dialog must show `bulkTargetCount`'s answer rather than a client-side
        tally.


        Shared across list services.
      properties:
        ids:
          type: array
          items:
            type: string
        filters:
          type: array
          items:
            $ref: '#/components/schemas/Input_ListFilterInput'
        search:
          type: string
        excludeIds:
          type: array
          items:
            type: string
    Success:
      type: object
      required:
        - status
        - message
        - data
      properties:
        status:
          type: boolean
          description: >-
            The actual resolver result. It can be false when an operation
            returns false or null without throwing.
        message:
          type: string
          example: OK
        data: {}
      description: Every 2xx response uses this envelope.
    Output_BulkResult:
      type: object
      description: >-
        The one shape every bulk mutation answers in, so the client renders one
        summary.

        `requested` is what the target RESOLVED to on the server, not what the
        client

        guessed. `refused` and `failed` are counted separately on purpose: a
        rule

        declining a row (an AS Colour garment, a draft purchase order) is not a
        failure,

        and collapsing the two makes correct behaviour read as breakage.


        Shared across list services.
      properties:
        requested:
          type: integer
        affected:
          type: integer
        refused:
          type: integer
        failed:
          type: integer
        outcomes:
          type: array
          items:
            $ref: '#/components/schemas/Output_BulkItemOutcome'
      required:
        - requested
        - affected
        - refused
        - failed
        - outcomes
    Error:
      type: object
      required:
        - error
        - message
        - status
      properties:
        error:
          type: string
          description: Stable machine-readable error code.
        message:
          type: string
        status:
          type: boolean
          const: false
      description: Every non-2xx response uses this envelope.
    Input_ListFilterInput:
      type: object
      description: >-
        One advanced-filter condition for a list query — mirrors the client's

        FilterBuilderButton. Shared across list services (see quote-service for
        the

        full field docs).
      properties:
        field:
          type: string
        op:
          type: string
        value:
          type: string
        values:
          type: array
          items:
            type: string
        from:
          type: string
        to:
          type: string
      required:
        - field
        - op
    Output_BulkItemOutcome:
      type: object
      description: >-
        What happened to one row in a bulk action. `reason` is null only for
        `ok`.
      properties:
        id:
          type: string
        status:
          $ref: '#/components/schemas/Enum_BulkOutcomeStatus'
        reason:
          type:
            - string
            - 'null'
      required:
        - id
        - status
    Enum_BulkOutcomeStatus:
      type: string
      description: >-
        Per-row verdict for a bulk action. `refused` is a rule saying no;
        `failed` is an error.
      enum:
        - ok
        - refused
        - failed
  securitySchemes:
    tenantApiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: Tenant credential. This is sufficient by itself.
    partnerApiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: Partner application client ID.
    partnerApiSecret:
      type: apiKey
      in: header
      name: X-API-Secret
      description: Partner application secret.
    partnerBearer:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Cognito access token obtained through OAuth.

````