Worders Quotes API

The Quotes API from Worders — 2 operation(s) for quotes.

OpenAPI Specification

worders-quotes-api-openapi.yml Raw ↑
openapi: 3.0.1
info:
  title: Worders API V1 Customers Quotes API
  version: v1
  description: Worders API endpoints (freelance invoice verification, webhooks, ...).
servers:
- url: https://api.worders.net
tags:
- name: Quotes
paths:
  /V1/quotes:
    get:
      summary: List quotes
      tags:
      - Quotes
      description: Returns quotes mirroring the quote PDF. Supports filtering by customer, status, and incremental polling via updated_since.
      security:
      - cookie_session: []
      - bearer_auth: []
      parameters:
      - name: customer_plunet_id
        in: query
        required: false
        schema:
          type: integer
      - name: status
        in: query
        required: false
        schema:
          type: string
      - name: updated_since
        in: query
        required: false
        schema:
          type: string
          format: date-time
      - name: page
        in: query
        required: false
        schema:
          type: integer
          default: 1
      - name: per_page
        in: query
        required: false
        schema:
          type: integer
          default: 50
      responses:
        '200':
          description: matching quotes
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Quote'
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'
        '401':
          description: unauthenticated
    post:
      summary: Create a Plunet quote with items
      tags:
      - Quotes
      description: 'Create a Quote + OrderItems in Plunet from Airtable-mapped data. Idempotent on `external_id`: the second POST returns 200 with the existing quote.'
      security:
      - bearer_auth: []
      parameters: []
      responses:
        '201':
          description: quote created in Plunet
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuoteCreateResponse'
        '200':
          description: returns the existing quote when external_id matches
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuoteCreateResponse'
        '404':
          description: unknown customer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '400':
          description: missing quote key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QuoteCreateRequest'
        required: true
  /V1/quotes/{id}:
    parameters:
    - name: id
      in: path
      required: true
      schema:
        type: string
      description: Plunet quote id (e.g. "Q-1000") or order_reference (e.g. "Q-1446-01").
    get:
      summary: Show a single quote
      tags:
      - Quotes
      security:
      - cookie_session: []
      - bearer_auth: []
      responses:
        '200':
          description: lookup by plunet_id
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Quote'
        '404':
          description: unknown quote
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    QuoteItem:
      type: object
      properties:
        id:
          type: string
          nullable: true
          example: I-44556
          description: Plunet item id
        plunet_id:
          type: string
          nullable: true
          description: Same as id
        language_source:
          type: string
          nullable: true
          example: en-US
        language_target:
          type: string
          nullable: true
          example: fr-FR
        client_price:
          type: number
          format: float
          nullable: true
          example: 49.5
          description: Item price in the customer-facing currency.
        status:
          type: string
          nullable: true
          example: invoiced
        price_line:
          type: array
          items:
            $ref: '#/components/schemas/PriceLineEntry'
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
            details:
              type: object
              nullable: true
          required:
          - code
          - message
      required:
      - error
    PaginationMeta:
      type: object
      properties:
        total:
          type: integer
          example: 42
        page:
          type: integer
          example: 1
        per_page:
          type: integer
          example: 50
    QuoteCreateRequest:
      type: object
      required:
      - quote
      properties:
        quote:
          type: object
          required:
          - customer
          - project_manager
          - items
          properties:
            external_id:
              type: string
              example: rec_AIRTABLE_RECORD_ID
              description: Airtable record id, used for idempotence
            customer:
              type: object
              description: Identify the customer by plunet_id, id (uuid) or name (one of)
              properties:
                plunet_id:
                  type: integer
                  example: 12345
                id:
                  type: string
                  format: uuid
                name:
                  type: string
            project_manager:
              type: object
              description: Identify the PM by email or id (uuid)
              properties:
                email:
                  type: string
                  format: email
                  example: pm@worders.net
                id:
                  type: string
                  format: uuid
            contact_person:
              type: object
              description: Optional. Identify by plunet_id (Plunet customer_contact_id) or email
              properties:
                plunet_id:
                  type: integer
                  example: 67890
                email:
                  type: string
                  format: email
            project_name:
              type: string
              example: Adobe — Acrobat Q2 update
            subject:
              type: string
              example: Translation of help articles
            currency:
              type: string
              example: EUR
            order_date:
              type: string
              format: date
              nullable: true
            delivery_deadline:
              type: string
              format: date-time
              nullable: true
            rate:
              type: number
              format: float
              nullable: true
              example: 0.1
            project_manager_memo:
              type: string
              nullable: true
            template_id:
              type: integer
              nullable: true
              example: 42
            items:
              type: array
              items:
                type: object
                properties:
                  language_source:
                    type: string
                    example: en-US
                  language_target:
                    type: string
                    example: fr-FR
                  quantity:
                    type: number
                    format: float
                    example: 1200
                  description:
                    type: string
                    nullable: true
                  delivery_date:
                    type: string
                    format: date
                    nullable: true
    QuoteCreateResponse:
      type: object
      properties:
        id:
          type: string
          nullable: true
          example: Q-12345
          description: Plunet quote id
        plunet_id:
          type: string
          nullable: true
          description: Same as id
        created:
          type: boolean
          description: true when newly created, false when idempotent hit on existing external_id
        order_reference:
          type: string
          nullable: true
          example: Q-1446-01
        status:
          type: string
          nullable: true
          example: in_preparation
        external_id:
          type: string
          nullable: true
        items:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
                nullable: true
                description: Plunet item id
              language_source:
                type: string
                nullable: true
              language_target:
                type: string
                nullable: true
        urls:
          type: object
          properties:
            worders_admin:
              type: string
              format: uri
            plunet:
              type: string
              format: uri
              nullable: true
    Quote:
      type: object
      properties:
        id:
          type: string
          example: Q-1446-01
          description: Quote order_reference
        plunet_id:
          type: string
          nullable: true
          description: Plunet quote id
        order_reference:
          type: string
          nullable: true
          description: Same as id; canonical reference like "Q-1446-01"
        created_at:
          type: string
          format: date-time
        valid_until:
          type: string
          format: date
          nullable: true
          description: Quote validity end date (created_at + 1 month).
        status:
          type: string
          nullable: true
          example: pending
        project_name:
          type: string
          nullable: true
        client_ccy:
          type: string
          nullable: true
          example: USD
        price_in_client_ccy:
          type: number
          format: float
          nullable: true
          example: 5778.0
        customer:
          $ref: '#/components/schemas/QuoteCustomer'
        contact_person:
          type: object
          nullable: true
          properties:
            full_name:
              type: string
              example: Amber Russell
            email:
              type: string
              format: email
              example: amberrussell@ebsco.com
        project_manager:
          type: object
          nullable: true
          properties:
            full_name:
              type: string
              example: Jane Doe
        items:
          type: array
          items:
            $ref: '#/components/schemas/QuoteItem'
    QuoteCustomer:
      type: object
      nullable: true
      properties:
        plunet_id:
          type: integer
          nullable: true
          example: 12345
        name:
          type: string
          example: EBSCO
        address:
          type: string
          nullable: true
          example: 'EBSCO

            10 Estes Street

            01938 Ipswich

            United States'
    PriceLineEntry:
      type: object
      properties:
        price_unit_id:
          type: integer
          nullable: true
          example: 12
        service:
          type: string
          nullable: true
          example: Culturalization
        unit:
          type: string
          nullable: true
          example: Hour
        amount:
          type: number
          format: float
          example: 0.55
        unit_price:
          type: number
          format: float
          example: 90.0
        total:
          type: number
          format: float
          example: 49.5
  securitySchemes:
    cookie_session:
      type: apiKey
      in: cookie
      name: _worders_session
      description: Authenticated Devise session cookie (api.worders.net).
    bearer_auth:
      type: http
      scheme: bearer
      description: 'Service API key issued from the admin UI. Sent as `Authorization: Bearer wrd_live_…`.'