Sendcloud Analytics API v3

Aggregated shipping spend, carrier mix, service-level performance, and return-rate analytics.

Sendcloud Analytics API v3 is one of 20 APIs that Sendcloud publishes on the APIs.io network, described by a machine-readable OpenAPI specification.

Tagged areas include Analytics and Reporting. The published artifact set on APIs.io includes API documentation and an OpenAPI specification.

OpenAPI Specification

sendcloud-v3-analytics-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Analytics
  version: 3.0.0
  description: >-
    The Analytics API exposes aggregated shipping insights derived from your
    account's shipping activity. The current release covers carrier and shipping
    option transit times.
  contact:
    name: Sendcloud API Support
    url: https://www.sendcloud.dev
    email: [email protected]
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html
servers:
  - url: https://panel.sendcloud.sc/api/v3
    description: Sendcloud Production
tags:
  - name: Analytics
paths:
  /analytics/transit-times/carriers:
    get:
      summary: Retrieve carrier transit times
      description: >-
        Returns aggregated transit-time statistics per carrier, optionally
        filtered by origin and destination country and a date window.
      x-mint:
        href: /api/v3/analytics/retrieve-carrier-transit-times
        metadata:
          tag: Beta
        content: >-
          Transit times are aggregated from your account's recent shipping
          activity. The response contains one record per `(carrier_code,
          from_country_code, to_country_code)` row; rows with no transit-time
          data are omitted. When `start_date` and `end_date` are omitted, the
          response covers the last 90 days (UTC). `start_date` must be on or
          before `end_date`.
      operationId: sc-public-v3-analytics-get-carrier_transit_times
      tags:
        - Analytics
      parameters:
        - name: carrier_code
          in: query
          required: true
          style: form
          explode: true
          description: >-
            One or more carrier codes to retrieve transit times for. Repeat the
            parameter to pass multiple values.
          schema:
            type: array
            minItems: 1
            items:
              type: string
              minLength: 1
            example:
              - postnl
              - dhl
        - $ref: '#/components/parameters/FromCountryCode'
        - $ref: '#/components/parameters/ToCountryCode'
        - $ref: '#/components/parameters/StartDate'
        - $ref: '#/components/parameters/EndDate'
      security:
        - HTTPBasicAuth: []
        - OAuth2ClientCreds: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CarrierTransitTimeResponse'
              examples:
                RetrieveCarrierTransitTimes:
                  summary: Retrieve carrier transit times
                  value:
                    transit_times:
                      - carrier_code: postnl
                        from_country_code: NL
                        to_country_code: AT
                        start_date: '2025-03-01T00:00:00Z'
                        end_date: '2025-03-31T23:59:59Z'
                        total_parcels: 1284
                        transit_time_hours: 48.5
                        transit_time_days: 2
                      - carrier_code: postnl
                        from_country_code: NL
                        to_country_code: DE
                        start_date: '2025-03-01T00:00:00Z'
                        end_date: '2025-03-31T23:59:59Z'
                        total_parcels: 932
                        transit_time_hours: 36.2
                        transit_time_days: 2
        '400':
          description: >-
            Bad Request. Returned when a request parameter fails validation or
            the request is semantically invalid. The `source.parameter` field
            identifies the offending input.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                InvalidDateRange:
                  summary: Invalid date range
                  value:
                    errors:
                      - status: '400'
                        code: invalid
                        detail: start_date must be on or before end_date.
                MissingRequiredParameter:
                  summary: Required parameter missing
                  value:
                    errors:
                      - status: '400'
                        code: missing
                        detail: Field required
                        source:
                          parameter: carrier_code
                InvalidCountryCode:
                  summary: Country code is not two characters
                  value:
                    errors:
                      - status: '400'
                        code: string_too_long
                        detail: String should have at most 2 characters
                        source:
                          parameter: from_country_code
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '502':
          $ref: '#/components/responses/BadGateway'
  /analytics/transit-times/shipping-options:
    get:
      summary: Retrieve shipping option transit times
      description: >-
        Returns aggregated transit-time statistics per shipping option,
        optionally filtered by origin and destination country and a date window.
      x-mint:
        href: /api/v3/analytics/retrieve-shipping-option-transit-times
        metadata:
          tag: Beta
        content: >-
          Transit times are aggregated from your account's recent shipping
          activity. The response contains one record per `(shipping_option_code,
          from_country_code, to_country_code)` row; rows with no transit-time
          data are omitted. When `start_date` and `end_date` are omitted, the
          response covers the last 90 days (UTC). `start_date` must be on or
          before `end_date`.
      operationId: sc-public-v3-analytics-get-shipping_option_transit_times
      tags:
        - Analytics
      parameters:
        - name: shipping_option_code
          in: query
          required: true
          style: form
          explode: true
          description: >-
            One or more shipping option codes to retrieve transit times for.
            Repeat the parameter to pass multiple values.
          schema:
            type: array
            minItems: 1
            items:
              type: string
              minLength: 1
              maxLength: 256
            example:
              - postnl_standard
              - dhl_express
        - $ref: '#/components/parameters/FromCountryCode'
        - $ref: '#/components/parameters/ToCountryCode'
        - $ref: '#/components/parameters/StartDate'
        - $ref: '#/components/parameters/EndDate'
      security:
        - HTTPBasicAuth: []
        - OAuth2ClientCreds: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ShippingOptionTransitTimeResponse'
              examples:
                RetrieveShippingOptionTransitTimes:
                  summary: Retrieve shipping option transit times
                  value:
                    transit_times:
                      - shipping_option_code: postnl_standard
                        from_country_code: NL
                        to_country_code: AT
                        start_date: '2025-03-01T00:00:00Z'
                        end_date: '2025-03-31T23:59:59Z'
                        total_parcels: 842
                        transit_time_hours: 50.1
                        transit_time_days: 2
                      - shipping_option_code: dhl_express
                        from_country_code: NL
                        to_country_code: DE
                        start_date: '2025-03-01T00:00:00Z'
                        end_date: '2025-03-31T23:59:59Z'
                        total_parcels: 217
                        transit_time_hours: 26.4
                        transit_time_days: 1
        '400':
          description: >-
            Bad Request. Returned when one or more request parameters fail
            validation (missing required parameters, country codes that aren't
            two characters, `shipping_option_code` outside its length bounds,
            dates outside the supported format) or when the request itself is
            semantically invalid (e.g. `start_date` after `end_date`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                InvalidDateRange:
                  summary: Invalid date range
                  value:
                    errors:
                      - status: '400'
                        code: invalid
                        detail: start_date must be on or before end_date.
                MissingRequiredParameter:
                  summary: Required parameter missing
                  value:
                    errors:
                      - status: '400'
                        code: missing
                        detail: Field required
                        source:
                          parameter: shipping_option_code
                InvalidCountryCode:
                  summary: Country code is not two characters
                  value:
                    errors:
                      - status: '400'
                        code: string_too_long
                        detail: String should have at most 2 characters
                        source:
                          parameter: from_country_code
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '502':
          $ref: '#/components/responses/BadGateway'
components:
  securitySchemes:
    HTTPBasicAuth:
      type: http
      description: >-
        Basic Authentication using API key and secrets is currently the main
        authentication mechanism.
      scheme: basic
    OAuth2ClientCreds:
      type: oauth2
      description: >-
        OAuth2 is a standardized protocol for authorization that allows users to
        share their private resources stored on one site with another site
        without having to provide their credentials. OAuth2 Client Credentials
        Grant workflow. This workflow is typically used for server-to-server
        interactions that require authorization to access specific resources.
      flows:
        clientCredentials:
          tokenUrl: https://account.sendcloud.com/oauth2/token/
          scopes:
            api: Default OAuth scope required to access Sendcloud API.
  parameters:
    FromCountryCode:
      name: from_country_code
      in: query
      required: false
      style: form
      explode: true
      description: >-
        ISO 3166-1 alpha-2 country codes of the origin to filter by. Repeat the
        parameter to pass multiple values.
      schema:
        type: array
        items:
          type: string
          minLength: 2
          maxLength: 2
        example:
          - NL
    ToCountryCode:
      name: to_country_code
      in: query
      required: false
      style: form
      explode: true
      description: >-
        ISO 3166-1 alpha-2 country codes of the destination to filter by. Repeat
        the parameter to pass multiple values.
      schema:
        type: array
        items:
          type: string
          minLength: 2
          maxLength: 2
        example:
          - AT
          - DE
    StartDate:
      name: start_date
      in: query
      required: false
      description: >-
        Inclusive start of the window in `YYYY-MM-DD` format. Defaults to 90
        days before today (UTC) when omitted.
      schema:
        type: string
        format: date
        example: '2025-03-01'
    EndDate:
      name: end_date
      in: query
      required: false
      description: >-
        Inclusive end of the window in `YYYY-MM-DD` format. Defaults to today
        (UTC) when omitted.
      schema:
        type: string
        format: date
        example: '2025-03-31'
  responses:
    Unauthorized:
      description: >-
        Unauthorized. Returned when authentication credentials are missing or
        invalid. Make sure you're using your **Public Key** as the username and
        **Secret Key** as the password (HTTP Basic Auth), or a valid OAuth 2.0
        access token.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            MissingCredentials:
              summary: No `Authorization` header on the request
              value:
                errors:
                  - status: '401'
                    code: authentication_failed
                    detail: Authentication credentials were not provided.
            InvalidCredentials:
              summary: Provided credentials don't match a Sendcloud account
              value:
                errors:
                  - status: '401'
                    code: authentication_failed
                    detail: Invalid username/password.
    Forbidden:
      description: >-
        Forbidden. Returned when your account doesn't have access to this
        endpoint.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            NotEnabled:
              summary: Account does not have access to the Analytics API
              value:
                errors:
                  - status: '403'
                    code: forbidden
                    detail: Analytics is not enabled for this organization.
    NotFound:
      description: >-
        Not Found. Returned when the analytics data source has not been
        provisioned for your organization. A successful query with no matching
        rows returns `200` with an empty `transit_times` array instead.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            NotProvisioned:
              summary: Analytics data source not provisioned
              value:
                errors:
                  - status: '404'
                    code: not_found
                    detail: Analytics data is not available for this organization.
    InternalServerError:
      description: >-
        Internal Server Error. Returned when the analytics data source is
        unreachable, times out, or returns an unexpected error. Safe to retry,
        but if it persists, contact support and include the request ID from the
        `X-Request-Id` response header.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            UpstreamUnavailable:
              summary: Analytics data source unavailable
              value:
                errors:
                  - status: '500'
                    code: unknown_error
                    detail: Failed to fetch analytics data. Please try again later.
    BadGateway:
      description: >-
        Bad Gateway. Returned when a request to an external service fails with
        an unexpected status. Safe to retry, but if it persists, contact support
        and include the request ID from the `X-Request-Id` response header.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            ExternalServiceError:
              summary: External service returned an error
              value:
                errors:
                  - status: '502'
                    code: external_service_error
                    detail: An error occurred with an external service.
  schemas:
    CarrierTransitTimeResponse:
      description: Response schema for the carrier transit times endpoint.
      type: object
      title: CarrierTransitTimeResponse
      properties:
        transit_times:
          type: array
          description: >-
            Aggregated transit-time records matching the requested filters. Rows
            with no transit-time data are omitted.
          items:
            $ref: '#/components/schemas/CarrierTransitTimeRecord'
      required:
        - transit_times
    CarrierTransitTimeRecord:
      description: >-
        A single aggregated transit-time record for a carrier and country pair
        over a date window.
      type: object
      title: CarrierTransitTimeRecord
      properties:
        carrier_code:
          type: string
          minLength: 1
          description: Unique identifier of the carrier the record applies to.
          example: postnl
        from_country_code:
          type:
            - string
            - 'null'
          minLength: 2
          maxLength: 2
          description: >-
            ISO 3166-1 alpha-2 country code of the origin, or `null` when the
            record is not scoped to a specific origin.
          example: NL
        to_country_code:
          type:
            - string
            - 'null'
          minLength: 2
          maxLength: 2
          description: >-
            ISO 3166-1 alpha-2 country code of the destination, or `null` when
            the record is not scoped to a specific destination.
          example: AT
        start_date:
          type: string
          format: date-time
          description: Inclusive start of the window the record covers.
          example: '2025-03-01T00:00:00Z'
        end_date:
          type: string
          format: date-time
          description: Inclusive end of the window the record covers.
          example: '2025-03-31T23:59:59Z'
        total_parcels:
          type: integer
          minimum: 0
          description: Number of parcels that contributed to the aggregate.
          example: 1284
        transit_time_hours:
          type: number
          format: float
          minimum: 0
          description: Median transit time in hours.
          example: 48.5
        transit_time_days:
          type: integer
          minimum: 0
          description: Median transit time in whole days.
          example: 2
      required:
        - carrier_code
        - from_country_code
        - to_country_code
        - start_date
        - end_date
        - total_parcels
        - transit_time_hours
        - transit_time_days
    ShippingOptionTransitTimeResponse:
      description: Response schema for the shipping option transit times endpoint.
      type: object
      title: ShippingOptionTransitTimeResponse
      properties:
        transit_times:
          type: array
          description: >-
            Aggregated transit-time records matching the requested filters. Rows
            with no transit-time data are omitted.
          items:
            $ref: '#/components/schemas/ShippingOptionTransitTimeRecord'
      required:
        - transit_times
    ShippingOptionTransitTimeRecord:
      description: >-
        A single aggregated transit-time record for a shipping option and
        country pair over a date window.
      type: object
      title: ShippingOptionTransitTimeRecord
      properties:
        shipping_option_code:
          type: string
          minLength: 1
          maxLength: 256
          description: Unique identifier of the shipping option the record applies to.
          example: postnl_standard
        from_country_code:
          type:
            - string
            - 'null'
          minLength: 2
          maxLength: 2
          description: >-
            ISO 3166-1 alpha-2 country code of the origin, or `null` when the
            record is not scoped to a specific origin.
          example: NL
        to_country_code:
          type:
            - string
            - 'null'
          minLength: 2
          maxLength: 2
          description: >-
            ISO 3166-1 alpha-2 country code of the destination, or `null` when
            the record is not scoped to a specific destination.
          example: AT
        start_date:
          type: string
          format: date-time
          description: Inclusive start of the window the record covers.
          example: '2025-03-01T00:00:00Z'
        end_date:
          type: string
          format: date-time
          description: Inclusive end of the window the record covers.
          example: '2025-03-31T23:59:59Z'
        total_parcels:
          type: integer
          minimum: 0
          description: Number of parcels that contributed to the aggregate.
          example: 842
        transit_time_hours:
          type: number
          format: float
          minimum: 0
          description: Median transit time in hours.
          example: 50.1
        transit_time_days:
          type: integer
          minimum: 0
          description: Median transit time in whole days.
          example: 2
      required:
        - shipping_option_code
        - from_country_code
        - to_country_code
        - start_date
        - end_date
        - total_parcels
        - transit_time_hours
        - transit_time_days
    ErrorResponse:
      type: object
      description: Standardized format for errors in JSON:API responses.
      properties:
        errors:
          type: array
          items:
            $ref: '#/components/schemas/ErrorObject'
      required:
        - errors
    ErrorObject:
      title: Error
      type: object
      description: Error in a JSON:API error format
      properties:
        id:
          type: string
          description: A unique identifier for the error.
        links:
          type: object
          description: >-
            A set of hyperlinks that provide additional information about the
            error.
          properties:
            about:
              type: string
              description: A URL that provides additional information about the error.
        status:
          type: string
          format: int32
          description: The HTTP status code of the error.
          minLength: 1
        code:
          type: string
          description: A unique error code for the error, in snake case format.
          minLength: 1
          enum:
            - unknown_field
            - invalid
            - forbidden
            - invalid_choice
            - min_value
            - 'null'
            - not_found
            - required
            - not_a_list
            - non_field_errors
            - authentication_failed
            - validation_error
            - parcel_announcement_error
        title:
          type: string
          description: A short, human-readable summary of the error.
          minLength: 1
        detail:
          type: string
          description: A human-readable explanation of the error.
          minLength: 1
        source:
          type: object
          description: >-
            An object that identifies the source of the error within the request
            payload.
          properties:
            pointer:
              type: string
              description: >-
                A `JSON` pointer to the location of the error within the request
                payload.
            parameter:
              type: string
              description: The name of the `query` parameter that caused the error.
            header:
              type: string
              description: The name of the `header` parameter that caused the error.
        meta:
          type: object
          description: Additional metadata about the error.