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

# Report Job Progress

> Worker progress update for a Job the caller created.

Single endpoint covering the lifecycle hooks an inbound-feed worker
needs: stage transitions, total_items updates, metadata cross-links
(e.g. ``import_job_id``), error/warning appends, and mark-started /
mark-completed / mark-failed transitions. Designed so customer-side
workers don't need a database connection — they call this with their
ServerApiKey authentication.

**Authorization:** Requires `job:create` permission (the same
permission needed to create the Job in the first place — the
creator owns follow-up updates). Multi-tenancy is enforced: the
request 404s if the Job's organization_id doesn't match the
caller's.



## OpenAPI

````yaml /openapi/merchantops-public.json post /api/jobs/{job_id}/progress
openapi: 3.1.0
info:
  description: >-
    Public API for the MerchantOps product catalog, pricing, and publishing
    surface.
  title: MerchantOps API
  version: 1.0.0
servers:
  - description: Production
    url: https://api.merchantops.ai
security: []
paths:
  /api/jobs/{job_id}/progress:
    post:
      tags:
        - Jobs
      summary: Report Job Progress
      description: |-
        Worker progress update for a Job the caller created.

        Single endpoint covering the lifecycle hooks an inbound-feed worker
        needs: stage transitions, total_items updates, metadata cross-links
        (e.g. ``import_job_id``), error/warning appends, and mark-started /
        mark-completed / mark-failed transitions. Designed so customer-side
        workers don't need a database connection — they call this with their
        ServerApiKey authentication.

        **Authorization:** Requires `job:create` permission (the same
        permission needed to create the Job in the first place — the
        creator owns follow-up updates). Multi-tenancy is enforced: the
        request 404s if the Job's organization_id doesn't match the
        caller's.
      operationId: report_job_progress
      parameters:
        - in: path
          name: job_id
          required: true
          schema:
            title: Job Id
            type: string
        - in: header
          name: authorization
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: Authorization
        - in: header
          name: X-Organization-ID
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: X-Organization-Id
        - in: cookie
          name: stytch_session
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: Stytch Session
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JobProgressRequest'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobResponse'
          description: Successful Response
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
          description: Validation Error
components:
  schemas:
    JobProgressRequest:
      description: >-
        Worker progress update — single endpoint for the lifecycle of a Job

        that the worker itself created.


        Designed for inbound-feed workers (e.g. rrs-oracle-import-worker) that

        don't have a database connection — they create the Job via POST
        /api/jobs/

        and then call this endpoint at each phase transition. All fields are

        optional; only provided fields take effect.
      properties:
        error:
          anyOf:
            - $ref: '#/components/schemas/JobProgressErrorBody'
            - type: 'null'
          description: Append an error to the Job's errors[] array
        mark_completed:
          default: false
          description: >-
            If true, mark the Job complete (auto-derives COMPLETED /
            COMPLETED_WITH_WARNINGS / PARTIAL_SUCCESS)
          title: Mark Completed
          type: boolean
        mark_failed:
          anyOf:
            - type: string
            - type: 'null'
          description: If set, mark the Job failed with this message as error_message
          title: Mark Failed
        mark_started:
          default: false
          description: If true, transition status to in_progress
          title: Mark Started
          type: boolean
        message:
          anyOf:
            - type: string
            - type: 'null'
          description: Optional log line stamped on metadata.last_message
          title: Message
        metadata_patch:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          description: >-
            Arbitrary metadata fields to merge under metadata.* — e.g.
            {'import_job_id': 'enrichment-...'} to cross-link the downstream
            job.
          title: Metadata Patch
        processed_items:
          anyOf:
            - minimum: 0
              type: integer
            - type: 'null'
          description: >-
            Set processed_items directly. Useful for inbound-feed workers that
            dispatch a batch downstream (e.g. via /import-json-async) and need
            the parent Job to reflect progress without a per-item NATS bus.
          title: Processed Items
        stage:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Sets metadata.stage (e.g. 'downloading', 'transforming',
            'uploading', 'dispatched').
          title: Stage
        total_items:
          anyOf:
            - minimum: 0
              type: integer
            - type: 'null'
          description: >-
            Update total_items (e.g. set after the worker counts the rows in a
            downloaded file).
          title: Total Items
        warning:
          anyOf:
            - $ref: '#/components/schemas/JobProgressErrorBody'
            - type: 'null'
          description: Append a warning to the Job's warnings[] array
      title: JobProgressRequest
      type: object
    JobResponse:
      description: Response model for a single Job.
      properties:
        completed_at:
          anyOf:
            - type: string
            - type: 'null'
          description: Job completion timestamp
          title: Completed At
        created_at:
          anyOf:
            - type: string
            - type: 'null'
          description: Job creation timestamp
          title: Created At
        duration_seconds:
          anyOf:
            - type: number
            - type: 'null'
          description: Job duration in seconds
          title: Duration Seconds
        error_message:
          anyOf:
            - type: string
            - type: 'null'
          description: 'DEPRECATED: Use ''errors'' array. Legacy error message'
          title: Error Message
        errors:
          description: Array of errors that occurred
          items:
            $ref: '#/components/schemas/JobErrorResponse'
          title: Errors
          type: array
        failed_items:
          description: Items that failed
          title: Failed Items
          type: integer
        job_id:
          description: Unique job identifier
          title: Job Id
          type: string
        job_type:
          description: Type of job (enrichment or crawl)
          title: Job Type
          type: string
        metadata:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          description: Job metadata
          title: Metadata
        processed_items:
          description: Items successfully processed
          title: Processed Items
          type: integer
        progress_percentage:
          description: Progress percentage (0-100)
          title: Progress Percentage
          type: number
        started_at:
          anyOf:
            - type: string
            - type: 'null'
          description: Job start timestamp
          title: Started At
        status:
          description: Current job status
          title: Status
          type: string
        success_rate:
          description: Success rate percentage (0-100)
          title: Success Rate
          type: number
        total_items:
          description: Total items to process
          title: Total Items
          type: integer
        triggered_by:
          anyOf:
            - type: string
            - type: 'null'
          description: User who triggered the job
          title: Triggered By
        warned_items:
          default: 0
          description: Items processed with warnings (e.g., expected target gaps)
          title: Warned Items
          type: integer
        warnings:
          description: Array of non-blocking warnings (same shape as errors)
          items:
            $ref: '#/components/schemas/JobErrorResponse'
          title: Warnings
          type: array
      required:
        - job_id
        - job_type
        - status
        - total_items
        - processed_items
        - failed_items
        - progress_percentage
        - success_rate
      title: JobResponse
      type: object
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          title: Detail
          type: array
      title: HTTPValidationError
      type: object
    JobProgressErrorBody:
      description: Error/warning entry to append to a Job's errors or warnings array.
      properties:
        details:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          description: Optional context
          title: Details
        entity_key:
          description: Key of the entity that failed
          title: Entity Key
          type: string
        entity_type:
          default: job
          description: Type of entity (job, product, …)
          title: Entity Type
          type: string
        error_type:
          description: Machine-readable error type
          title: Error Type
          type: string
        message:
          description: Human-readable error message
          title: Message
          type: string
        step:
          anyOf:
            - type: string
            - type: 'null'
          description: Step where the error occurred
          title: Step
      required:
        - entity_key
        - error_type
        - message
      title: JobProgressErrorBody
      type: object
    JobErrorResponse:
      description: Response model for a single job error.
      properties:
        details:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          description: Additional error context
          title: Details
        entity_key:
          description: Key of the entity that failed
          title: Entity Key
          type: string
        entity_type:
          description: Type of entity (product, document, etc.)
          title: Entity Type
          type: string
        error_type:
          description: Type of error
          title: Error Type
          type: string
        message:
          description: Human-readable error message
          title: Message
          type: string
        step:
          anyOf:
            - type: string
            - type: 'null'
          description: Step where the error occurred
          title: Step
        timestamp:
          description: When the error occurred (ISO 8601)
          title: Timestamp
          type: string
      required:
        - entity_key
        - entity_type
        - error_type
        - message
        - timestamp
      title: JobErrorResponse
      type: object
    ValidationError:
      properties:
        ctx:
          title: Context
          type: object
        input:
          title: Input
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          title: Location
          type: array
        msg:
          title: Message
          type: string
        type:
          title: Error Type
          type: string
      required:
        - loc
        - msg
        - type
      title: ValidationError
      type: object

````