parcelLab API

parcelLab API v4 Enhanced — the unified REST API for ingesting orders and trackings, retrieving order status, looking up pickup/drop-off locations, predicting delivery dates (Promise), creating and managing return registrations against returns configurations, evaluating campaign targeting, and serving surveys back to customers.

parcelLab API is one of 2 APIs that parcelLab publishes on the APIs.io network, described by a machine-readable OpenAPI specification.

This API exposes 7 machine-runnable capabilities that can be deployed as REST, MCP, or Agent Skill surfaces via Naftiko and 8 JSON Schema definitions.

Tagged areas include Orders, Tracking, Returns, Promise, and Surveys. The published artifact set on APIs.io includes API documentation, an API reference, a quickstart, authentication docs, an OpenAPI specification, a JSON-LD context, 7 Naftiko capability specs, and 8 JSON Schemas.

Documentation

Specifications

Examples

Schemas & Data

Other Resources

OpenAPI Specification

parcellab-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: parcelLab API
  description: |
    parcelLab API v4 Enhanced — the REST API for the parcelLab post-purchase
    experience platform. Send orders and trackings, retrieve order status,
    look up pickup/drop-off locations, predict delivery dates, manage return
    registrations and configurations, evaluate marketing campaigns, and
    publish surveys to your customers.

    Regional base URLs are available for EU and US workloads in addition to
    the global endpoint.
  version: '4'
  contact:
    name: parcelLab Developer Support
    url: https://docs.parcellab.com/docs/developers/readme
  license:
    name: Proprietary
    url: https://parcellab.com/legal/terms-of-service/
servers:
  - url: https://api.parcellab.com
    description: Global production endpoint
  - url: https://api.eu.parcellab.com
    description: EU regional endpoint
  - url: https://api.us.parcellab.com
    description: US regional endpoint
tags:
  - name: Orders
    description: Create, update, and inspect orders and their trackings.
  - name: Events
    description: Send custom shop or warehouse events into the tracking timeline.
  - name: Place Info
    description: Look up nearby pickup and drop-off (PUDO) locations.
  - name: Promise
    description: Pre-checkout delivery date predictions.
  - name: Returns
    description: Return registrations, configurations, and document templates.
  - name: Campaigns
    description: Evaluate campaign targeting and redirect analytics events.
  - name: Surveys
    description: Retrieve survey definitions and submit responses.
security:
  - parcellabApiToken: []
paths:
  /v4/track/orders/:
    put:
      tags: [Orders]
      summary: Create or Update Order
      operationId: upsertOrder
      description: >-
        Idempotent endpoint that creates a new order or applies mutations to
        an existing one (add or cancel trackings, change line item quantity,
        add or replace line items, cancel order).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrderUpsertRequest'
      responses:
        '200':
          description: Order updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderUpsertResponse'
        '201':
          description: New order created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderUpsertResponse'
        '400': { $ref: '#/components/responses/BadRequest' }
        '401': { $ref: '#/components/responses/Unauthorized' }
        '403': { $ref: '#/components/responses/Forbidden' }
  /v4/track/orders/info/:
    get:
      tags: [Orders]
      summary: Get Order Status
      operationId: getOrderInfo
      description: >-
        Retrieve the latest order, tracking, and checkpoint information for
        an order identified by order_number, tracking_number,
        external_order_id, or recipient identifiers.
      parameters:
        - { in: query, name: account, schema: { type: integer } }
        - { in: query, name: order_number, schema: { type: string } }
        - { in: query, name: tracking_number, schema: { type: string } }
        - { in: query, name: courier, schema: { type: string } }
        - { in: query, name: external_order_id, schema: { type: string, format: uuid } }
        - { in: query, name: external_reference, schema: { type: string } }
        - { in: query, name: customer_number, schema: { type: string } }
        - { in: query, name: recipient_email, schema: { type: string, format: email } }
        - { in: query, name: recipient_postal_code, schema: { type: string } }
        - { in: query, name: client_key, schema: { type: string } }
        - { in: query, name: lang, schema: { type: string, default: en } }
        - { in: query, name: s, schema: { type: string }, description: HMAC security signature. }
        - { in: query, name: live_refresh, schema: { type: boolean } }
        - { in: query, name: show_returns, schema: { type: boolean } }
        - { in: query, name: tracking_id, schema: { type: string } }
        - { in: query, name: single_tracking, schema: { type: boolean } }
      responses:
        '200':
          description: Order info.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderInfo'
        '400': { $ref: '#/components/responses/BadRequest' }
        '401': { $ref: '#/components/responses/Unauthorized' }
  /v4/track/events/:
    post:
      tags: [Events]
      summary: Send Shop or Warehouse Event
      operationId: sendShopEvent
      description: >-
        Push a custom event/checkpoint (e.g., warehouse pick, pack, dispatch)
        into the order timeline. Identifies the order by courier+tracking,
        account+reference, or account+order_number.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ShopEvent'
      responses:
        '204': { description: Event accepted. }
        '400': { $ref: '#/components/responses/BadRequest' }
        '401': { $ref: '#/components/responses/Unauthorized' }
  /v4/track/place-info/lookup/:
    post:
      tags: [Place Info]
      summary: Look Up Pickup/Drop-Off Locations
      operationId: lookupPlaceInfo
      description: >-
        Find nearby PUDO points for one or more couriers, ranked by distance
        from a geo-coordinate or address.
      parameters:
        - { in: query, name: account, schema: { type: array, items: { type: integer } } }
        - { in: query, name: ordering, schema: { type: string } }
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PlaceInfoLookupRequest'
      responses:
        '200':
          description: Matching PUDO points.
          content:
            application/json:
              schema:
                type: array
                items: { $ref: '#/components/schemas/PlaceInfoLookupResponseItem' }
        '400': { $ref: '#/components/responses/BadRequest' }
        '403': { $ref: '#/components/responses/Forbidden' }
  /v4/promise/prediction/predict/:
    get:
      tags: [Promise]
      summary: Predict Delivery Date
      operationId: predictDelivery
      description: >-
        Return localized delivery date predictions for a destination,
        optionally constrained to a courier, service level, and warehouse.
      parameters:
        - { in: query, name: account, required: true, schema: { type: integer } }
        - { in: query, name: destination_country_iso3, required: true, schema: { type: string } }
        - { in: query, name: destination_postal_code, schema: { type: string } }
        - { in: query, name: courier, schema: { type: string } }
        - { in: query, name: service_level, schema: { type: string } }
        - { in: query, name: warehouse, schema: { type: string } }
        - { in: query, name: language_iso2, schema: { type: string } }
        - { in: query, name: calibration, schema: { type: string, enum: [conservative, balanced, aggressive] } }
        - { in: query, name: dispatch_now, schema: { type: boolean } }
        - { in: query, name: now_override, schema: { type: string, format: date-time } }
        - { in: query, name: draft, schema: { type: boolean } }
      responses:
        '200':
          description: Delivery date predictions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PromisePrediction'
        '400': { $ref: '#/components/responses/BadRequest' }
  /v4/returns/return-registrations/:
    get:
      tags: [Returns]
      summary: List Return Registrations
      operationId: listReturnRegistrations
      parameters:
        - { in: query, name: account, schema: { type: integer } }
        - { in: query, name: limit, schema: { type: integer } }
        - { in: query, name: offset, schema: { type: integer } }
        - { in: query, name: ordering, schema: { type: string } }
      responses:
        '200':
          description: Page of return registrations.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReturnRegistrationList'
    post:
      tags: [Returns]
      summary: Create Return Registration
      operationId: createReturnRegistration
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ReturnRegistration'
      responses:
        '201':
          description: Created.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/ReturnRegistration' }
        '400': { $ref: '#/components/responses/BadRequest' }
  /v4/returns/return-registrations/{external_id}/:
    get:
      tags: [Returns]
      summary: Get Return Registration
      operationId: getReturnRegistration
      parameters:
        - { in: path, name: external_id, required: true, schema: { type: string, format: uuid } }
      responses:
        '200':
          description: Return registration.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/ReturnRegistration' }
        '404': { $ref: '#/components/responses/NotFound' }
  /v4/returns/returns-configurations/:
    get:
      tags: [Returns]
      summary: List Return Configurations
      operationId: listReturnConfigurations
      parameters:
        - { in: query, name: account, schema: { type: integer } }
        - { in: query, name: limit, schema: { type: integer } }
        - { in: query, name: offset, schema: { type: integer } }
        - { in: query, name: ordering, schema: { type: string } }
      responses:
        '200':
          description: Return configuration sets.
          content:
            application/json:
              schema:
                type: array
                items: { $ref: '#/components/schemas/ReturnConfiguration' }
  /v4/returns/returns-configurations/{id}/:
    get:
      tags: [Returns]
      summary: Get Return Configuration
      operationId: getReturnConfiguration
      parameters:
        - { in: path, name: id, required: true, schema: { type: string } }
      responses:
        '200':
          description: Return configuration.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/ReturnConfiguration' }
        '404': { $ref: '#/components/responses/NotFound' }
  /v4/returns/document-templates/:
    get:
      tags: [Returns]
      summary: List Document Templates
      operationId: listDocumentTemplates
      description: Document templates used for generating return labels and slips.
      parameters:
        - { in: query, name: account, schema: { type: integer } }
        - { in: query, name: limit, schema: { type: integer } }
        - { in: query, name: offset, schema: { type: integer } }
      responses:
        '200':
          description: Document templates.
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  additionalProperties: true
  /v4/campaign/evaluate/:
    get:
      tags: [Campaigns]
      summary: Evaluate Campaign Targeting
      operationId: evaluateCampaign
      parameters:
        - { in: query, name: accountId, schema: { type: integer } }
        - { in: query, name: campaignId, schema: { type: string } }
        - { in: query, name: language, schema: { type: string } }
        - { in: query, name: medium, schema: { type: string } }
        - { in: query, name: message, schema: { type: string } }
        - { in: query, name: orderNumber, schema: { type: string } }
        - { in: query, name: preview, schema: { type: boolean } }
        - { in: query, name: status, schema: { type: string } }
        - { in: query, name: trackingId, schema: { type: string } }
      responses:
        '200':
          description: Evaluated campaign content.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
  /v4/campaign/redirect/:
    get:
      tags: [Campaigns]
      summary: Campaign Redirect Analytics
      operationId: campaignRedirect
      parameters:
        - { in: query, name: campaignId, schema: { type: string } }
        - { in: query, name: trackingId, schema: { type: string } }
        - { in: query, name: eventType, required: true, schema: { type: string } }
        - { in: query, name: medium, schema: { type: string } }
        - { in: query, name: redirectUrl, schema: { type: string, format: uri } }
        - { in: query, name: customerSegmentationId, schema: { type: string } }
        - { in: query, name: emailId, schema: { type: string } }
        - { in: query, name: contentType, schema: { type: string } }
      responses:
        '302':
          description: Redirect to target URL.
  /v4/survey/survey/{id}/:
    get:
      tags: [Surveys]
      summary: Get Survey
      operationId: getSurvey
      parameters:
        - { in: path, name: id, required: true, schema: { type: string, format: uuid } }
      responses:
        '200':
          description: Survey definition.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/PublicSurvey' }
        '404': { $ref: '#/components/responses/NotFound' }
  /v4/survey/survey/{id}/answer/:
    get:
      tags: [Surveys]
      summary: Get Survey Answer
      operationId: getSurveyAnswer
      parameters:
        - { in: path, name: id, required: true, schema: { type: string, format: uuid } }
        - { in: query, name: ref_id, required: true, schema: { type: string } }
        - { in: query, name: reference_type, schema: { type: string, enum: [return_registration, tracking] } }
      responses:
        '200':
          description: Survey with prefilled answers.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/PublicSurvey' }
    post:
      tags: [Surveys]
      summary: Submit Survey Answer
      operationId: submitSurveyAnswer
      parameters:
        - { in: path, name: id, required: true, schema: { type: string, format: uuid } }
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/SurveyResponseRequest' }
      responses:
        '200':
          description: Submission accepted.
          content:
            application/json:
              schema: { $ref: '#/components/schemas/SurveyResponseResponse' }
        '400': { $ref: '#/components/responses/BadRequest' }
  /v4/survey/survey/themes/:
    get:
      tags: [Surveys]
      summary: List Survey Themes
      operationId: listSurveyThemes
      parameters:
        - { in: query, name: default, schema: { type: boolean } }
      responses:
        '200':
          description: Survey theme configurations.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
components:
  securitySchemes:
    parcellabApiToken:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        `Authorization: Parcellab-API-Token <base64(account_id:token)>`. App-
        generated tokens may instead use the `Bearer <token>` scheme.
  responses:
    BadRequest:
      description: Invalid payload or query parameters.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/ErrorResponse' }
    Unauthorized:
      description: Missing or invalid API token.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/ErrorResponse' }
    Forbidden:
      description: Token lacks required permissions.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/ErrorResponse' }
    NotFound:
      description: Resource not found.
      content:
        application/json:
          schema: { $ref: '#/components/schemas/ErrorResponse' }
  schemas:
    ErrorResponse:
      type: object
      properties:
        success: { type: boolean, example: false }
        message: { type: string }
        errors:
          type: object
          additionalProperties: true
    Address:
      type: object
      properties:
        name: { type: string }
        street: { type: string }
        house_no: { type: string }
        city: { type: string }
        postal_code: { type: string }
        country_iso3: { type: string }
        state: { type: string }
        phone: { type: string }
        email: { type: string, format: email }
    LineItem:
      type: object
      properties:
        sku: { type: string }
        name: { type: string }
        quantity: { type: integer }
        price: { type: number }
        currency: { type: string }
        image_url: { type: string, format: uri }
    Mutation:
      type: object
      properties:
        type:
          type: string
          enum:
            - add_tracking
            - cancel_tracking
            - cancel_order
            - change_line_item_quantity
            - add_line_item
            - replace_line_item
        payload:
          type: object
          additionalProperties: true
    OrderUpsertRequest:
      type: object
      required: [account, order_number]
      properties:
        account: { type: integer }
        order_number: { type: string }
        destination_country_iso3: { type: string }
        recipient_email: { type: string, format: email }
        recipient_name: { type: string }
        shipping_address: { $ref: '#/components/schemas/Address' }
        articles_order:
          type: array
          items: { $ref: '#/components/schemas/LineItem' }
        mutations:
          type: array
          items: { $ref: '#/components/schemas/Mutation' }
    OrderUpsertResponse:
      type: object
      properties:
        external_id: { type: string, format: uuid }
        order_number: { type: string }
        mutations:
          type: array
          items:
            type: object
            properties:
              type: { type: string }
              result:
                type: object
                properties:
                  success: { type: boolean }
                  message: { type: string }
                  errors: { type: object, additionalProperties: true }
                  warnings:
                    type: array
                    items: { type: string }
    Checkpoint:
      type: object
      properties:
        timestamp: { type: string, format: date-time }
        status: { type: string }
        status_details: { type: string }
        location: { type: string }
        courier: { type: string }
    Tracking:
      type: object
      properties:
        tracking_number: { type: string }
        courier: { type: string }
        status: { type: string }
        lifecycle: { type: string }
        delivery_estimate: { type: string, format: date-time }
        checkpoints:
          type: array
          items: { $ref: '#/components/schemas/Checkpoint' }
    OrderInfo:
      type: object
      properties:
        order_number: { type: string }
        client_key: { type: string }
        order_date: { type: string, format: date-time }
        recipient_name: { type: string }
        recipient_email: { type: string, format: email }
        destination_country_iso3: { type: string }
        trackings:
          type: array
          items: { $ref: '#/components/schemas/Tracking' }
    ShopEvent:
      type: object
      required: [event_timestamp, event_status]
      properties:
        event_timestamp: { type: string, format: date-time }
        event_status: { type: string }
        location: { type: string }
        event_details: { type: string }
        placeholder_value: { type: string }
        courier: { type: string }
        tracking_number: { type: string }
        account: { type: integer }
        reference_number: { type: string }
        order_number: { type: string }
    PlaceInfoLookupItem:
      type: object
      properties:
        courier: { type: string }
        service_level: { type: string }
        query: { type: string }
    PlaceInfoLookupRequest:
      type: object
      required: [account, lookups, country_iso3]
      properties:
        account: { type: integer }
        country_iso3: { type: string }
        lookups:
          type: array
          minItems: 1
          maxItems: 3
          items: { $ref: '#/components/schemas/PlaceInfoLookupItem' }
        location:
          type: object
          properties:
            latitude: { type: number }
            longitude: { type: number }
        external_reference: { type: string }
        location_address: { $ref: '#/components/schemas/Address' }
    PlaceInfoLookupResponseItem:
      type: object
      properties:
        courier: { type: string }
        place_type:
          type: string
          enum: [default, self-service, partner, store, other]
        address: { $ref: '#/components/schemas/Address' }
        location:
          type: object
          properties:
            latitude: { type: number }
            longitude: { type: number }
        opening_hours:
          type: object
          additionalProperties: true
        distance_meters: { type: integer }
        services:
          type: array
          items: { type: string }
        phone: { type: string }
        website: { type: string, format: uri }
        external_reference: { type: string }
    PromisePrediction:
      type: object
      properties:
        request_id: { type: string }
        success: { type: boolean }
        prediction:
          type: array
          items:
            type: object
            properties:
              courier: { type: string }
              service_level: { type: string }
              date_min: { type: string, format: date }
              date_max: { type: string, format: date }
              date_likely: { type: string, format: date }
              days_min: { type: integer }
              days_max: { type: integer }
              days_likely: { type: integer }
              cutoff: { type: string, format: date-time }
              localized:
                type: object
                additionalProperties: true
    ReturnRegistration:
      type: object
      required: [account, code, reference, customer_email]
      properties:
        external_id: { type: string, format: uuid, readOnly: true }
        sequence_number: { type: string, readOnly: true }
        account: { type: integer }
        code: { type: string, maxLength: 255 }
        reference: { type: string, maxLength: 255 }
        customer_email: { type: string }
        customer_address: { $ref: '#/components/schemas/Address' }
        status:
          type: string
          enum:
            - created
            - submitted
            - pending_approval
            - pending_label
            - approved
            - rejected
            - cancelled
            - closed
            - processing_failed
            - invalid
        order_date: { type: string, format: date-time }
        order_delivery_date: { type: string, format: date-time }
        order_shipping_date: { type: string, format: date-time }
        order_total_amount: { type: number }
        order_shipping_amount: { type: number }
        order_tax_amount: { type: number }
        order_currency: { type: string }
        articles_order:
          type: array
          items: { $ref: '#/components/schemas/LineItem' }
        articles_return:
          type: array
          items: { $ref: '#/components/schemas/LineItem' }
        return_labels:
          type: array
          readOnly: true
          items:
            type: object
            additionalProperties: true
        tags:
          type: array
          items: { type: string }
        metadata:
          type: object
          additionalProperties: true
        created_at: { type: string, format: date-time, readOnly: true }
        updated_at: { type: string, format: date-time, readOnly: true }
    ReturnRegistrationList:
      type: object
      properties:
        count: { type: integer }
        next: { type: string, format: uri, nullable: true }
        previous: { type: string, format: uri, nullable: true }
        results:
          type: array
          items: { $ref: '#/components/schemas/ReturnRegistration' }
    ReturnConfiguration:
      type: object
      properties:
        id: { type: string }
        account: { type: integer }
        code: { type: string }
        name: { type: string }
        return_periods:
          type: array
          items:
            type: object
            additionalProperties: true
        return_reasons:
          type: array
          items:
            type: object
            additionalProperties: true
        compensation_methods:
          type: array
          items:
            type: object
            additionalProperties: true
        carrier_options:
          type: array
          items:
            type: object
            additionalProperties: true
    PublicSurvey:
      type: object
      properties:
        id: { type: string, format: uuid }
        name: { type: string }
        status: { type: string }
        type: { type: string }
        surveyUrl: { type: string, format: uri }
        config:
          type: object
          additionalProperties: true
        editable: { type: boolean }
    SurveyResponseRequest:
      type: object
      properties:
        data:
          type: object
          additionalProperties: true
        is_complete: { type: boolean }
        reference_id: { type: string }
        reference_type:
          type: string
          enum: [return_registration, tracking]
    SurveyResponseResponse:
      type: object
      properties:
        isComplete: { type: boolean }
        detail: { type: string }