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

# Import an invoice from documents

> Imports an invoice from one uploaded primary document and up to 50 attachments (each file at least 100 bytes; the primary up to 50 MiB, attachments up to 25 MiB). Poll GET /v1/invoices/imports/{id} until status is completed, failed or cancelled. A completed import has outcome imported, duplicate or not_invoice; when it has an invoice_id, poll the invoice until workflows.settled.

The primary document must be a PDF or an XML invoice or credit note (Peppol BIS Billing 3.0 or EHF 2.0); any other file fails the import with validation_error. If the XML cannot be used, an attached PDF or HTML version of the same invoice is used instead. Attachments can be any file type, such as spreadsheets, Word documents or emails; they are read when the invoice is checked.

If the primary document is already an invoice's primary document, the import completes at once as a duplicate of that invoice, without using capacity. Each new import uses invoice processing capacity. Idempotency-Key is optional; a replay returns the same import in its current state.



## OpenAPI

````yaml /openapi.json post /v1/invoices/imports
openapi: 3.1.0
info:
  title: Watchdog API
  version: 1.0.0
  description: >-
    The Watchdog API is served from https://api.watchdog.no. Request bodies are
    limited to 2 MiB unless an endpoint says otherwise. Files are uploaded
    directly to storage, not through the API.
servers:
  - url: https://api.watchdog.no
    description: Watchdog API
security: []
paths:
  /v1/invoices/imports:
    post:
      tags:
        - Invoice imports
        - Invoices
      summary: Import an invoice from documents
      description: >-
        Imports an invoice from one uploaded primary document and up to 50
        attachments (each file at least 100 bytes; the primary up to 50 MiB,
        attachments up to 25 MiB). Poll GET /v1/invoices/imports/{id} until
        status is completed, failed or cancelled. A completed import has outcome
        imported, duplicate or not_invoice; when it has an invoice_id, poll the
        invoice until workflows.settled.


        The primary document must be a PDF or an XML invoice or credit note
        (Peppol BIS Billing 3.0 or EHF 2.0); any other file fails the import
        with validation_error. If the XML cannot be used, an attached PDF or
        HTML version of the same invoice is used instead. Attachments can be any
        file type, such as spreadsheets, Word documents or emails; they are read
        when the invoice is checked.


        If the primary document is already an invoice's primary document, the
        import completes at once as a duplicate of that invoice, without using
        capacity. Each new import uses invoice processing capacity.
        Idempotency-Key is optional; a replay returns the same import in its
        current state.
      operationId: createInvoiceImport
      parameters:
        - name: X-Organization-Id
          in: header
          required: false
          schema:
            type: string
          description: >-
            The organization to act in. Required for personal API keys; list the
            organizations you can access with GET /v1/organizations.
        - name: Idempotency-Key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 200
            pattern: ^[\x21-\x7e]+$
          description: >-
            Optional protection for safely retrying a request after a timeout or
            lost response. Choose a unique value (for example, a UUID) for each
            action and reuse it with the same input when retrying. Omit it for a
            normal request.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                primary_document_id:
                  type: string
                  format: uuid
                  description: The uploaded document that contains the invoice.
                attachment_document_ids:
                  type: array
                  items:
                    type: string
                    format: uuid
                  maxItems: 50
                  default: []
                  description: >-
                    Up to 50 other uploaded documents, in order. Must not
                    include the primary document.
              required:
                - primary_document_id
              additionalProperties: false
            example:
              primary_document_id: 11111111-1111-4111-8111-111111111111
              attachment_document_ids:
                - 22222222-2222-4222-8222-222222222222
      responses:
        '200':
          description: 'Idempotent replay: the same import in its current state.'
          headers:
            X-Request-Id:
              schema:
                type: string
              required: true
              description: >-
                Request ID, also included in error bodies. Include it when
                contacting support.
            Cache-Control:
              schema:
                type: string
                enum:
                  - private, no-store
                  - private, no-store, no-transform
              required: false
              description: API responses are private and must not be cached.
            X-RateLimit-Limit:
              schema:
                type: string
                example: '500'
              required: false
              description: >-
                Requests allowed per minute for this credential, or failed API
                key attempts allowed per minute from this IP address.
            Location:
              schema:
                type: string
              required: false
              description: Relative URL of the created or accepted resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvoiceImport'
        '202':
          description: 'The new import: queued, or already completed as a duplicate.'
          headers:
            X-Request-Id:
              schema:
                type: string
              required: true
              description: >-
                Request ID, also included in error bodies. Include it when
                contacting support.
            Cache-Control:
              schema:
                type: string
                enum:
                  - private, no-store
                  - private, no-store, no-transform
              required: false
              description: API responses are private and must not be cached.
            X-RateLimit-Limit:
              schema:
                type: string
                example: '500'
              required: false
              description: >-
                Requests allowed per minute for this credential, or failed API
                key attempts allowed per minute from this IP address.
            Location:
              schema:
                type: string
              required: false
              description: Relative URL of the created or accepted resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvoiceImport'
        '400':
          description: >-
            The request is invalid. details lists up to 20 field errors. Request
            bodies are limited to 2 MiB.
          headers:
            X-Request-Id:
              schema:
                type: string
              required: true
              description: >-
                Request ID, also included in error bodies. Include it when
                contacting support.
            Cache-Control:
              schema:
                type: string
                enum:
                  - private, no-store
                  - private, no-store, no-transform
              required: false
              description: API responses are private and must not be cached.
            X-RateLimit-Limit:
              schema:
                type: string
                example: '500'
              required: false
              description: >-
                Requests allowed per minute for this credential, or failed API
                key attempts allowed per minute from this IP address.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error_validation_error'
              example:
                error:
                  code: validation_error
                  message: >-
                    The request is invalid. details lists up to 20 field errors.
                    Request bodies are limited to 2 MiB.
                  request_id: req_example
        '401':
          description: The bearer token is missing or invalid.
          headers:
            X-Request-Id:
              schema:
                type: string
              required: true
              description: >-
                Request ID, also included in error bodies. Include it when
                contacting support.
            Cache-Control:
              schema:
                type: string
                enum:
                  - private, no-store
                  - private, no-store, no-transform
              required: false
              description: API responses are private and must not be cached.
            X-RateLimit-Limit:
              schema:
                type: string
                example: '500'
              required: false
              description: >-
                Requests allowed per minute for this credential, or failed API
                key attempts allowed per minute from this IP address.
            WWW-Authenticate:
              schema:
                type: string
              required: false
              description: Bearer authentication challenge, when supplied.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error_invalid_token'
              example:
                error:
                  code: invalid_token
                  message: The bearer token is missing or invalid.
                  request_id: req_example
        '403':
          description: >-
            Access denied, or invoice_processing_capacity_exhausted: the
            organization has no invoice processing capacity left. Nothing was
            imported.
          headers:
            X-Request-Id:
              schema:
                type: string
              required: true
              description: >-
                Request ID, also included in error bodies. Include it when
                contacting support.
            Cache-Control:
              schema:
                type: string
                enum:
                  - private, no-store
                  - private, no-store, no-transform
              required: false
              description: API responses are private and must not be cached.
            X-RateLimit-Limit:
              schema:
                type: string
                example: '500'
              required: false
              description: >-
                Requests allowed per minute for this credential, or failed API
                key attempts allowed per minute from this IP address.
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/Error_forbidden_token_disabled_organization_required_insufficient_role_mfa_required_invoice_processing_capacity_exhausted
              example:
                error:
                  code: forbidden
                  message: >-
                    Access denied, or invoice_processing_capacity_exhausted: the
                    organization has no invoice processing capacity left.
                    Nothing was imported.
                  request_id: req_example
        '409':
          description: >-
            conflict: the Idempotency-Key was used with a different request, the
            import cannot be changed in its current state, or a document already
            belongs to another invoice. source_unavailable: an uploaded file is
            missing or has changed.
          headers:
            X-Request-Id:
              schema:
                type: string
              required: true
              description: >-
                Request ID, also included in error bodies. Include it when
                contacting support.
            Cache-Control:
              schema:
                type: string
                enum:
                  - private, no-store
                  - private, no-store, no-transform
              required: false
              description: API responses are private and must not be cached.
            X-RateLimit-Limit:
              schema:
                type: string
                example: '500'
              required: false
              description: >-
                Requests allowed per minute for this credential, or failed API
                key attempts allowed per minute from this IP address.
            Location:
              schema:
                type: string
              required: false
              description: Relative URL of the created or accepted resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error_conflict_source_unavailable'
              example:
                error:
                  code: conflict
                  message: >-
                    conflict: the Idempotency-Key was used with a different
                    request, the import cannot be changed in its current state,
                    or a document already belongs to another invoice.
                    source_unavailable: an uploaded file is missing or has
                    changed.
                  request_id: req_example
        '429':
          description: Too many requests. Wait for the Retry-After delay before retrying.
          headers:
            X-Request-Id:
              schema:
                type: string
              required: true
              description: >-
                Request ID, also included in error bodies. Include it when
                contacting support.
            Cache-Control:
              schema:
                type: string
                enum:
                  - private, no-store
                  - private, no-store, no-transform
              required: false
              description: API responses are private and must not be cached.
            X-RateLimit-Limit:
              schema:
                type: string
                example: '500'
              required: false
              description: >-
                Requests allowed per minute for this credential, or failed API
                key attempts allowed per minute from this IP address.
            Retry-After:
              schema:
                type: string
                example: '60'
              required: true
              description: Seconds to wait before retrying the request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error_rate_limit_exceeded'
              example:
                error:
                  code: rate_limit_exceeded
                  message: >-
                    Too many requests. Wait for the Retry-After delay before
                    retrying.
                  request_id: req_example
        '500':
          description: >-
            Unexpected server failure. Include the request ID when contacting
            support.
          headers:
            X-Request-Id:
              schema:
                type: string
              required: true
              description: >-
                Request ID, also included in error bodies. Include it when
                contacting support.
            Cache-Control:
              schema:
                type: string
                enum:
                  - private, no-store
                  - private, no-store, no-transform
              required: false
              description: API responses are private and must not be cached.
            X-RateLimit-Limit:
              schema:
                type: string
                example: '500'
              required: false
              description: >-
                Requests allowed per minute for this credential, or failed API
                key attempts allowed per minute from this IP address.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error_internal_error'
              example:
                error:
                  code: internal_error
                  message: >-
                    Unexpected server failure. Include the request ID when
                    contacting support.
                  request_id: req_example
        '503':
          description: >-
            The service is temporarily unavailable. If error.import_id is
            present, the import exists: read its status before retrying.
          headers:
            X-Request-Id:
              schema:
                type: string
              required: true
              description: >-
                Request ID, also included in error bodies. Include it when
                contacting support.
            Cache-Control:
              schema:
                type: string
                enum:
                  - private, no-store
                  - private, no-store, no-transform
              required: false
              description: API responses are private and must not be cached.
            X-RateLimit-Limit:
              schema:
                type: string
                example: '500'
              required: false
              description: >-
                Requests allowed per minute for this credential, or failed API
                key attempts allowed per minute from this IP address.
            Location:
              schema:
                type: string
              required: false
              description: Relative URL of the created or accepted resource.
            Retry-After:
              schema:
                type: string
                example: '60'
              required: true
              description: Seconds to wait before retrying the request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error_service_unavailable'
              example:
                error:
                  code: service_unavailable
                  message: >-
                    The service is temporarily unavailable. If error.import_id
                    is present, the import exists: read its status before
                    retrying.
                  request_id: req_example
      security:
        - ApiKeyBearer: []
components:
  schemas:
    InvoiceImport:
      allOf:
        - $ref: '#/components/schemas/InvoiceImportSummary'
        - type: object
          properties:
            sources:
              type: array
              items:
                type: object
                properties:
                  document:
                    $ref: '#/components/schemas/Document'
                  role:
                    type: string
                    enum:
                      - primary
                      - attachment
                  position:
                    type: integer
                required:
                  - document
                  - role
                  - position
            sources_next_cursor:
              type:
                - string
                - 'null'
            evidence:
              type: array
              items:
                type: object
                properties:
                  stage:
                    type: string
                    enum:
                      - inspection
                      - header
                      - lines
                      - xml
                  succeeded:
                    type: boolean
                  created_at:
                    type: string
                    format: date-time
                  confidence_level:
                    type:
                      - string
                      - 'null'
                    enum:
                      - high
                      - mid
                      - low
                      - null
                  confidence_reason:
                    type:
                      - string
                      - 'null'
                    maxLength: 2000
                required:
                  - stage
                  - succeeded
                  - created_at
                  - confidence_level
                  - confidence_reason
              maxItems: 4
              description: >-
                The latest result of each extraction step, for diagnostics. More
                steps may be added.
          required:
            - sources
            - sources_next_cursor
            - evidence
    Error_validation_error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - validation_error
            message:
              type: string
            request_id:
              type: string
            description:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  code:
                    type: string
                  field:
                    type: string
                  message:
                    type: string
                required:
                  - code
                  - field
                  - message
              maxItems: 20
            workflow_run_id:
              type: string
              format: uuid
            import_id:
              type: string
              format: uuid
            existing_party:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - supplier
                    - recipient
                id:
                  type: string
                  format: uuid
              required:
                - type
                - id
          required:
            - code
            - message
            - request_id
      required:
        - error
    Error_invalid_token:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - invalid_token
            message:
              type: string
            request_id:
              type: string
            description:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  code:
                    type: string
                  field:
                    type: string
                  message:
                    type: string
                required:
                  - code
                  - field
                  - message
              maxItems: 20
            workflow_run_id:
              type: string
              format: uuid
            import_id:
              type: string
              format: uuid
            existing_party:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - supplier
                    - recipient
                id:
                  type: string
                  format: uuid
              required:
                - type
                - id
          required:
            - code
            - message
            - request_id
      required:
        - error
    Error_forbidden_token_disabled_organization_required_insufficient_role_mfa_required_invoice_processing_capacity_exhausted:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - forbidden
                - token_disabled
                - organization_required
                - insufficient_role
                - mfa_required
                - invoice_processing_capacity_exhausted
            message:
              type: string
            request_id:
              type: string
            description:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  code:
                    type: string
                  field:
                    type: string
                  message:
                    type: string
                required:
                  - code
                  - field
                  - message
              maxItems: 20
            workflow_run_id:
              type: string
              format: uuid
            import_id:
              type: string
              format: uuid
            existing_party:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - supplier
                    - recipient
                id:
                  type: string
                  format: uuid
              required:
                - type
                - id
          required:
            - code
            - message
            - request_id
      required:
        - error
    Error_conflict_source_unavailable:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - conflict
                - source_unavailable
            message:
              type: string
            request_id:
              type: string
            description:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  code:
                    type: string
                  field:
                    type: string
                  message:
                    type: string
                required:
                  - code
                  - field
                  - message
              maxItems: 20
            workflow_run_id:
              type: string
              format: uuid
            import_id:
              type: string
              format: uuid
            existing_party:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - supplier
                    - recipient
                id:
                  type: string
                  format: uuid
              required:
                - type
                - id
          required:
            - code
            - message
            - request_id
      required:
        - error
    Error_rate_limit_exceeded:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - rate_limit_exceeded
            message:
              type: string
            request_id:
              type: string
            description:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  code:
                    type: string
                  field:
                    type: string
                  message:
                    type: string
                required:
                  - code
                  - field
                  - message
              maxItems: 20
            workflow_run_id:
              type: string
              format: uuid
            import_id:
              type: string
              format: uuid
            existing_party:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - supplier
                    - recipient
                id:
                  type: string
                  format: uuid
              required:
                - type
                - id
          required:
            - code
            - message
            - request_id
      required:
        - error
    Error_internal_error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - internal_error
            message:
              type: string
            request_id:
              type: string
            description:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  code:
                    type: string
                  field:
                    type: string
                  message:
                    type: string
                required:
                  - code
                  - field
                  - message
              maxItems: 20
            workflow_run_id:
              type: string
              format: uuid
            import_id:
              type: string
              format: uuid
            existing_party:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - supplier
                    - recipient
                id:
                  type: string
                  format: uuid
              required:
                - type
                - id
          required:
            - code
            - message
            - request_id
      required:
        - error
    Error_service_unavailable:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - service_unavailable
            message:
              type: string
            request_id:
              type: string
            description:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  code:
                    type: string
                  field:
                    type: string
                  message:
                    type: string
                required:
                  - code
                  - field
                  - message
              maxItems: 20
            workflow_run_id:
              type: string
              format: uuid
            import_id:
              type: string
              format: uuid
            existing_party:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - supplier
                    - recipient
                id:
                  type: string
                  format: uuid
              required:
                - type
                - id
          required:
            - code
            - message
            - request_id
      required:
        - error
    InvoiceImportSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
        status:
          type: string
          enum:
            - queued
            - running
            - completed
            - failed
            - cancelled
        origin:
          type: string
          enum:
            - upload
            - api
            - email
            - integration
          description: How the invoice was submitted.
        supersedes_invoice:
          type: boolean
          description: >-
            True when this import replaces an existing invoice from the same
            source.
        deleted_at:
          type:
            - string
            - 'null'
          format: date-time
        primary_document:
          anyOf:
            - $ref: '#/components/schemas/Document'
            - type: 'null'
        source_count:
          type: integer
          minimum: 0
        attachment_count:
          type: integer
          minimum: 0
        retryable:
          type: boolean
          description: Whether the import can be retried.
        provenance:
          type: object
          properties:
            uploader:
              type:
                - object
                - 'null'
              properties:
                user_id:
                  type: string
                name:
                  type:
                    - string
                    - 'null'
                deleted:
                  type: boolean
                  description: >-
                    The uploader account was deleted. The name is kept, or null
                    once the account is anonymised.
              required:
                - user_id
                - name
                - deleted
            api_key:
              type:
                - object
                - 'null'
              properties:
                name:
                  type: string
              required:
                - name
            email:
              type:
                - object
                - 'null'
              properties:
                sender:
                  type:
                    - string
                    - 'null'
                name:
                  type:
                    - string
                    - 'null'
              required:
                - sender
                - name
            integration:
              type:
                - object
                - 'null'
              properties:
                id:
                  type: string
                  format: uuid
                name:
                  type: string
                type:
                  type: string
                deleted:
                  type: boolean
                  description: The integration was deleted after it delivered the file.
              required:
                - id
                - name
                - type
                - deleted
          required:
            - uploader
            - api_key
            - email
            - integration
        classification_reason:
          type:
            - string
            - 'null'
        outcome:
          type:
            - string
            - 'null'
          enum:
            - imported
            - duplicate
            - not_invoice
            - null
        invoice_id:
          type:
            - string
            - 'null'
          format: uuid
        workflow_run_id:
          type: string
          format: uuid
        workflow_run_item_id:
          type: string
          format: uuid
        failure:
          type:
            - object
            - 'null'
          properties:
            code:
              type: string
            message:
              type: string
          required:
            - code
            - message
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - status
        - origin
        - supersedes_invoice
        - deleted_at
        - primary_document
        - source_count
        - attachment_count
        - retryable
        - provenance
        - classification_reason
        - outcome
        - invoice_id
        - workflow_run_id
        - workflow_run_item_id
        - failure
        - created_at
        - updated_at
    Document:
      type: object
      properties:
        id:
          type: string
          format: uuid
        file_name:
          type: string
        mime_type:
          type:
            - string
            - 'null'
        file_size:
          type:
            - integer
            - 'null'
        page_count:
          type:
            - integer
            - 'null'
        md5_checksum:
          type:
            - string
            - 'null'
          description: Base64 MD5 of the file. Null until the upload has been verified.
        properties:
          oneOf:
            - type: object
              properties:
                kind:
                  type: string
                  enum:
                    - workbook
                sheets:
                  type: array
                  items:
                    type: object
                    properties:
                      name:
                        type: string
                      hidden:
                        type: boolean
                      row_count:
                        type: integer
                        minimum: 0
                    required:
                      - name
                      - hidden
                      - row_count
              required:
                - kind
                - sheets
            - type: 'null'
          description: >-
            What the file contains, keyed by `kind`. For `workbook` (XLSX): each
            worksheet in order, with its `name`, whether it is `hidden`, and
            `row_count` (rows with at least one non-empty cell). Null when not
            available for this file.
        created_at:
          type: string
          format: date-time
        updated_at:
          type:
            - string
            - 'null'
          format: date-time
        version:
          type:
            - integer
            - 'null'
        previous_version_id:
          type:
            - string
            - 'null'
          format: uuid
      required:
        - id
        - file_name
        - mime_type
        - file_size
        - page_count
        - md5_checksum
        - properties
        - created_at
        - updated_at
        - version
        - previous_version_id
  securitySchemes:
    ApiKeyBearer:
      type: http
      scheme: bearer
      description: >-
        Personal API key sent as a bearer token, together with
        X-Organization-Id. The key must have at least the access level the
        endpoint requires (read, write or admin).

````

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