Skip to main content
Every Reporting API run needs a report type and a date interval. The interval picks which rows you export. This page covers how to set an interval the API accepts, how to choose output columns, and how idempotency keys work.

Discover what a report type accepts

Read a report type’s metadata before you build a create-run request. It tells you the columns the report type can output and the data window you can request.
cURL
Auth uses the ShippoToken header; see the authentication guide. This abbreviated response shows one available column:
  • available_columns[] lists the columns this report type can output. is_default marks the columns selected when you omit columns from a run.
  • data_availability shows the data window you can request. start and end bound the window in UTC epoch seconds, and updated is when those bounds were last checked. A status of pending means the report type isn’t runnable yet.

Choose your columns

columns is optional. Leave it out and you get the columns where is_default is true. To choose the output explicitly, send a list of column name values from available_columns[]. The result keeps those columns in the order you submit. A column name that is not listed in available_columns returns 400 invalid-column.

Set a date interval

interval is required. It’s two integer UTC epoch seconds, not milliseconds and not ISO strings.
  • end has to be strictly greater than start. Equal or inverted bounds return 422 validation-error.
  • The span can’t exceed 92 days. Over the limit returns 400 invalid-parameter, and the message gives you the exact cap. For a longer span, split it into multiple runs.
  • The interval has to fall inside data_availability. Outside the ready window returns 404 data-unavailable.

Create a run

cURL
A run starts as QUEUED, moves to PROCESSING, then ends as SUCCEEDED or FAILED. Poll GET /v2/reporting/runs/{run_id} until it reaches one of those terminal states. The returned download URL is time-limited; fetch the run again to obtain a new URL. output_format is optional. Pick csv, csv_gzip, or parquet. Leave it out and you get csv_gzip.

Retry safely with an idempotency key

idempotency_key is an optional string you supply, 1 to 128 characters. It lets you retry a create without risking a duplicate run. Without a key, every create makes a new run, so reuse the key if you want a retry to be safe. With the same key and the identical request, you can replay as many times as you need. On a 409, pick a new key or send the original request.

Errors

After authentication, Reporting API errors use application/problem+json. Match errors on the last path segment of type, not the full URI. Handle authentication failures by their 401 HTTP status.
Match Reporting API errors on the last path segment of type (e.g. invalid-parameter), not the full URI. Authentication failures may instead be 401 application/json; handle them by HTTP status.
A run can also fail after it is queued. That comes back as 200 OK with status: FAILED and an error object whose code is one of invalid_run_request, run_failed, run_processing_failed, run_timeout, or service_unavailable.

Next steps

Create and poll a report run

Walk the full async lifecycle from create through download.

Reporting API reference

Full schema, fields, and error responses.
Last modified on September 16, 2026