openapi: 3.1.0
info:
  title: StatusPro API
  description: Use this API to retrieve and update the status of an order.
  version: 1.0.0
  license:
    name: Proprietary
    identifier: LicenseRef-Proprietary
servers:
- url: https://app.orderstatuspro.com/api/v1
  description: Production
security:
- bearerAuth: []
tags:
- name: Orders
  description: Order retrieval, status updates, comments, due dates, and lookup operations.
- name: Statuses
  description: Status definition and viable-status listing operations.
paths:
  /orders/{order}/status:
    post:
      tags:
      - Orders
      summary: Update an order status
      description: Limited to 60 requests per minute.
      operationId: updateOrderStatus
      parameters:
      - name: order
        in: path
        required: true
        description: The ID of the order.
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateOrderStatusRequest'
            example:
              status_code: st000002
              comment: This is a comment
              public: true
              email_customer: true
              email_additional: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageResponse'
              example:
                message: Order status updated successfully!
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /orders/bulk-status:
    post:
      tags:
      - Orders
      summary: Queue a bulk status update for up to 50 orders
      description: Limited to 5 requests per minute.
      operationId: bulkUpdateOrderStatus
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BulkStatusUpdateRequest'
            example:
              order_ids:
              - 6110375248088
              - 6110375248089
              status_code: st000003
              comment: Batch moved to shipped
              public: false
              email_customer: true
              email_additional: false
      responses:
        '202':
          description: Accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkStatusUpdateResponse'
              example:
                message: Bulk status update queued.
                count: 2
                limit: 50
        '400':
          $ref: '#/components/responses/BadRequest'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /orders/{order}/comment:
    post:
      tags:
      - Orders
      summary: Add a comment to the order
      description: Limited to 60 requests per minute.
      operationId: addOrderComment
      parameters:
      - name: order
        in: path
        required: true
        description: The ID of the order.
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddOrderCommentRequest'
            example:
              comment: This is a comment
              public: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageResponse'
              example:
                message: Order comment added!
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /orders/{order}/due-date:
    post:
      tags:
      - Orders
      summary: Set a due date on the order
      description: Limited to 60 requests per minute.
      operationId: setOrderDueDate
      parameters:
      - name: order
        in: path
        required: true
        description: The ID of the order.
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SetDueDateRequest'
            example:
              due_date: '2026-02-10'
              due_date_to: '2026-02-12'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageResponse'
              example:
                message: Order due date set!
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /orders:
    get:
      tags:
      - Orders
      summary: Retrieve a paginated list of orders
      description: Limited to 60 requests per minute.
      operationId: listOrders
      parameters:
      - name: search
        in: query
        required: false
        description: Filter by partial match against order name, order number, customer name, or customer email.
        schema:
          type: string
      - name: status_code
        in: query
        required: false
        description: Filter by a single status code like st000002.
        schema:
          type: string
          minLength: 8
          maxLength: 8
      - name: tags[]
        in: query
        required: false
        description: Filter by tags that must all be present using repeated query params such as tags[]=commercial&tags[]=commercial-lease.
        schema:
          type: array
          items:
            type: string
        style: form
        explode: true
        examples:
          allTags:
            summary: Only orders containing every tag
            value:
            - commercial
            - commercial-lease
      - name: tags_any[]
        in: query
        required: false
        description: Filter by tags where any listed tag may be present using repeated query params such as tags_any[]=commercial&tags_any[]=commercial-flooring.
        schema:
          type: array
          items:
            type: string
        style: form
        explode: true
        examples:
          anyTags:
            summary: Orders matching any listed tag
            value:
            - commercial-flooring
            - commercial-rental
      - name: financial_status[]
        in: query
        required: false
        description: 'Filter by one or more financial statuses using repeated query params such as financial_status[]=partially_paid&financial_status[]=pending.
          Accepted values: paid, partially_paid, partially_refunded, refunded, voided, pending, authorized, unpaid.'
        schema:
          type: array
          items:
            type: string
            enum:
            - paid
            - partially_paid
            - partially_refunded
            - refunded
            - voided
            - pending
            - authorized
            - unpaid
        style: form
        explode: true
        examples:
          dueStatuses:
            summary: Capture all due orders
            value:
            - partially_paid
            - pending
            - unpaid
      - name: fulfillment_status[]
        in: query
        required: false
        description: 'Filter by one or more fulfillment statuses using repeated query params such as fulfillment_status[]=fulfilled.
          Accepted values: unfulfilled, partial, restocked, fulfilled.'
        schema:
          type: array
          items:
            type: string
            enum:
            - unfulfilled
            - partial
            - restocked
            - fulfilled
        style: form
        explode: true
        examples:
          fulfilledOnly:
            summary: Only fulfilled orders
            value:
            - fulfilled
      - name: exclude_cancelled
        in: query
        required: false
        description: When true, excludes orders where cancelled_at is set.
        schema:
          type: boolean
        example: true
      - name: due_date_from
        in: query
        required: false
        description: Filter to orders with a due date on or after this `YYYY-MM-DD` date.
        schema:
          type: string
          format: date
      - name: due_date_to
        in: query
        required: false
        description: Filter to orders with a due date on or before this `YYYY-MM-DD` date.
        schema:
          type: string
          format: date
      - name: per_page
        in: query
        required: false
        description: Number of orders to return per page. Defaults to 15. Maximum 100.
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 15
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderListResponse'
              example:
                data:
                - id: 6110375248088
                  name: '#1188'
                  order_number: '1188'
                  customer:
                    name: Jon Smith
                    email: jon@example.com
                    locale: en
                  status:
                    is_set: true
                    code: st000002
                    name: In Production
                    public_name: Crafting With Care
                    description: Order being handcrafted in the workshop
                    color: '#F59E0B'
                    public: true
                    set_at: '2026-03-12T10:14:00+00:00'
                    auto_change_at: null
                  due_date: '2026-03-15T00:00:00+00:00'
                  due_date_to: '2026-03-17T00:00:00+00:00'
                  history_count: 4
                meta:
                  current_page: 1
                  from: 1
                  last_page: 1
                  per_page: 15
                  to: 1
                  total: 1
        '400':
          $ref: '#/components/responses/BadRequest'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /orders/{order}:
    get:
      tags:
      - Orders
      summary: Retrieve details of a specific order
      description: Limited to 60 requests per minute.
      operationId: getOrder
      parameters:
      - name: order
        in: path
        required: true
        description: The ID of the order.
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /statuses:
    get:
      tags:
      - Statuses
      summary: Get all defined statuses for your account
      description: Limited to 60 requests per minute.
      operationId: getStatuses
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/StatusDefinition'
              example:
              - name: Order Received
                description: We have received your order.
                code: st000001
                color: gray
              - name: In Production
                description: Your order is being handcrafted in the workshop.
                code: st000002
                color: pink
              - name: Shipped
                description: Order has been shipped and is on its way.
                code: st000003
                color: green
        '400':
          $ref: '#/components/responses/BadRequest'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /orders/lookup:
    get:
      tags:
      - Orders
      summary: Retrieve an order by order number and customer email
      description: Limited to 60 requests per minute.
      operationId: lookupOrder
      parameters:
      - name: number
        in: query
        required: true
        description: 'Order number or name (for example: 1188 or #1188).'
        schema:
          type: string
      - name: email
        in: query
        required: true
        description: Customer email address.
        schema:
          type: string
          format: email
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /orders/{order}/viable-statuses:
    get:
      tags:
      - Orders
      - Statuses
      summary: Get viable statuses for an order
      description: Limited to 60 requests per minute.
      operationId: getViableStatuses
      parameters:
      - name: order
        in: path
        required: true
        description: The ID of the order.
        schema:
          type: integer
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ViableStatus'
              example:
              - code: st000002
                name: In Production
                description: Order being handcrafted in the workshop
                color: pink
              - code: st000003
                name: Shipped
                description: Safely packed and dispatched
                color: green
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
  responses:
    BadRequest:
      description: Bad Request. The request was malformed or missing required headers.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotFound:
      description: Not Found. The requested resource does not exist.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    UnprocessableEntity:
      description: Unprocessable Entity. The request was well-formed but contains invalid data or failed validation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ValidationErrorResponse'
    TooManyRequests:
      description: Too Many Requests. The request was rate limited. Wait before retrying.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    InternalServerError:
      description: Internal Server Error. An unexpected error occurred.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  schemas:
    ErrorResponse:
      type: object
      properties:
        message:
          type: string
    ValidationErrorResponse:
      type: object
      properties:
        message:
          type: string
        errors:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
    MessageResponse:
      type: object
      required:
      - message
      properties:
        message:
          type: string
    UpdateOrderStatusRequest:
      type: object
      required:
      - status_code
      properties:
        status_code:
          type: string
        comment:
          type: string
        public:
          type: boolean
          default: false
        email_customer:
          type: boolean
          default: true
        email_additional:
          type: boolean
          default: true
    BulkStatusUpdateRequest:
      type: object
      required:
      - order_ids
      - status_code
      properties:
        order_ids:
          type: array
          minItems: 1
          maxItems: 50
          items:
            type: integer
        status_code:
          type: string
        comment:
          type: string
        public:
          type: boolean
          default: false
        email_customer:
          type: boolean
          default: true
        email_additional:
          type: boolean
          default: true
        send_at:
          type: integer
          description: Unix timestamp to schedule status emails.
        due_date:
          type: string
          format: date
    BulkStatusUpdateResponse:
      type: object
      required:
      - message
      - count
      - limit
      properties:
        message:
          type: string
        count:
          type: integer
        limit:
          type: integer
    AddOrderCommentRequest:
      type: object
      required:
      - comment
      properties:
        comment:
          type: string
          minLength: 3
          maxLength: 1000
        public:
          type: boolean
          default: false
    SetDueDateRequest:
      type: object
      required:
      - due_date
      properties:
        due_date:
          type:
          - string
          - 'null'
          format: date
        due_date_to:
          type: string
          format: date
    Customer:
      type: object
      properties:
        name:
          type: string
        email:
          type: string
          format: email
        locale:
          type: string
    LocaleTranslation:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
    Status:
      type: object
      properties:
        is_set:
          type: boolean
        code:
          type: string
        name:
          type: string
        public_name:
          type:
          - string
          - 'null'
        description:
          type: string
        public:
          type: boolean
        set_at:
          type:
          - string
          - 'null'
          format: date-time
        auto_change_at:
          type:
          - string
          - 'null'
          format: date-time
        translations:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/LocaleTranslation'
    MailLog:
      type: object
      properties:
        from:
          type: string
          format: email
        to:
          type: string
          format: email
        subject:
          type: string
        delivery_status:
          type: string
    HistoryItem:
      type: object
      properties:
        event:
          type: string
        status:
          anyOf:
          - $ref: '#/components/schemas/Status'
          - type: 'null'
        comment:
          type:
          - string
          - 'null'
        comment_is_public:
          type: boolean
        created_at:
          type: string
          format: date-time
        mail_log:
          anyOf:
          - $ref: '#/components/schemas/MailLog'
          - type: 'null'
    ProgressTimelineItem:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        progress:
          type: string
        timestamp:
          type:
          - string
          - 'null'
    OrderResponse:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        order_number:
          type: string
        customer:
          $ref: '#/components/schemas/Customer'
        status:
          $ref: '#/components/schemas/Status'
        history:
          type: array
          items:
            $ref: '#/components/schemas/HistoryItem'
        public_progress_timeline:
          type: array
          items:
            $ref: '#/components/schemas/ProgressTimelineItem'
        due_date:
          type:
          - string
          - 'null'
          format: date-time
        due_date_to:
          type:
          - string
          - 'null'
          format: date-time
    OrderListItem:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        order_number:
          type: string
        customer:
          $ref: '#/components/schemas/Customer'
        status:
          $ref: '#/components/schemas/Status'
        due_date:
          type:
          - string
          - 'null'
          format: date-time
        due_date_to:
          type:
          - string
          - 'null'
          format: date-time
        history_count:
          type: integer
    OrderListMeta:
      type: object
      properties:
        current_page:
          type: integer
        from:
          type:
          - integer
          - 'null'
        last_page:
          type: integer
        per_page:
          type: integer
        to:
          type:
          - integer
          - 'null'
        total:
          type: integer
    OrderListResponse:
      type: object
      required:
      - data
      - meta
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/OrderListItem'
        meta:
          $ref: '#/components/schemas/OrderListMeta'
    StatusDefinition:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        code:
          type: string
        color:
          type: string
    ViableStatus:
      type: object
      properties:
        code:
          type: string
        name:
          type: string
        description:
          type: string
        color:
          type: string
