> ## Documentation Index
> Fetch the complete documentation index at: https://docs.goshippo.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Shippo is a multi-carrier shipping API. For agent integrations that execute shipping operations (rates, labels, tracking, address validation, customs), connect the hosted Shippo MCP server at https://mcp.shippo.com (per-user OAuth; setup at /guides/mcp-server). To search and read this documentation from an agent, a docs search MCP is available at https://docs.goshippo.com/mcp. Shipping workflow knowledge (agent skills and a knowledge pack) is published at https://github.com/goshippo/ai. For REST integrations start at /guides/api-quickstart; test mode uses shippo_test_ API keys.

# Reporting API overview

> The Reporting API exports your Shippo account data as downloadable CSV or Parquet files via async runs you create, poll, and download.

The Reporting API turns your Shippo account data into downloadable CSV or Parquet files. Pick a report type, request a time interval, and Reporting API builds the file for you. The work happens asynchronously, so you create a run, poll until it's ready, then download it. See the [Authentication guide](/guides/authentication) for token setup.

## Report types

A **report type** is a predefined report identified by a versioned key (`{name}.v{version}`).

| `report_type` | Covers                                 |
| ------------- | -------------------------------------- |
| `invoice.v1`  | Account invoices, charges, and refunds |

Call `GET /v2/reporting/reports` to fetch the live catalog. It returns the currently active report types and their available columns. See [Discover available reports](/reporting-api/discover-reports).

## Endpoints

Base URL: `https://api.goshippo.com`

| Method | Path                                  | Purpose                  |
| ------ | ------------------------------------- | ------------------------ |
| `GET`  | `/v2/reporting/reports`               | List active report types |
| `GET`  | `/v2/reporting/reports/{report_type}` | Columns and data window  |
| `POST` | `/v2/reporting/runs`                  | Create an async run      |
| `GET`  | `/v2/reporting/runs`                  | List your recent runs    |
| `GET`  | `/v2/reporting/runs/{run_id}`         | Get or poll one run      |

An unknown `run_id` returns a `404`.

## Run states

Reporting API uses uppercase run statuses to match Shippo's existing reports API lifecycle vocabulary.

| `status`     | Meaning                              | Terminal |
| ------------ | ------------------------------------ | -------- |
| `QUEUED`     | Queued, not built yet                | No       |
| `PROCESSING` | Generating                           | No       |
| `SUCCEEDED`  | File ready, download URL attached    | Yes      |
| `FAILED`     | Could not complete, `error` attached | Yes      |

<Warning>
  A run with `status: FAILED` is **HTTP 200** with `status: FAILED`, not an HTTP error. Read the `error` object to handle it.
</Warning>

There's no webhook. Poll `GET /v2/reporting/runs/{run_id}` until the run reaches a terminal status.

## Example flow

**1. Create a run.** Set `interval.start` and `interval.end` in UTC epoch seconds. `end` must be greater than `start`, otherwise you get a `422`. A single run can span up to 92 days; a longer window returns `400 invalid-parameter`.

```shell title="cURL" theme={null}
curl https://api.goshippo.com/v2/reporting/runs \
  -H "Authorization: ShippoToken <API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "report_type": "invoice.v1",
    "interval": { "start": 1704067200, "end": 1706745600 },
    "output_format": "csv_gzip"
  }'
```

You get `201 Created` with `status: QUEUED`.

<Info>Idempotency is opt-in. Send an optional `idempotency_key`, any string of 1 to 128 characters, to make retries safe. Reuse the same key with the same request and you get the existing run back as **HTTP 200** instead of a duplicate. Reuse the same key with a different request and you get a **409** (`idempotency-conflict`). Skip the key and every create starts a new run, so there's no automatic deduplication.</Info>

**2. Poll until terminal.**

```shell title="cURL" theme={null}
curl https://api.goshippo.com/v2/reporting/runs/f47ac10b-58cc-4372-a567-0e02b2c3d479 \
  -H "Authorization: ShippoToken <API_TOKEN>"
```

Once the run reaches `SUCCEEDED`, the response includes `result.download.url`.

<Info>The download URL expires at `result.download.expires`, expressed as a UTC epoch second. If it expires, fetch the run again for a new URL.</Info>

**3. Download.** Send a `GET` request to `result.download.url`. A Shippo `Authorization` header is not required for this request.

```shell title="cURL" theme={null}
curl -o invoices-jan-2024.csv.gz "https://<download-host>/<opaque-path>?<signature>"
```

See [Download report files](/reporting-api/download-artifacts).

## Errors

Reporting API errors use RFC 7807 `application/problem+json`, except authentication failures, which use `401 application/json` with a `detail` field. Match problem responses on the trailing error-code segment of `type`, since its host can change.

Common codes:

| Code                   | HTTP | When                                                      |
| ---------------------- | ---- | --------------------------------------------------------- |
| `invalid-column`       | 400  | A requested column is not in the report type's catalog    |
| `invalid-parameter`    | 400  | Bad interval or out-of-range window (over 92 days)        |
| `validation-error`     | 422  | Malformed request, such as `end` not greater than `start` |
| `idempotency-conflict` | 409  | Reused an `idempotency_key` with a different request      |
| `service-unavailable`  | 503  | Temporary outage; retry later                             |

A run with `status: FAILED` comes back as **HTTP 200** with `status: FAILED`, and its `error` object carries a failure code: `invalid_run_request`, `run_failed`, `run_processing_failed`, `run_timeout`, or `service_unavailable`.

Other statuses you may see: `401`, `404`. See [Errors and run failures](/reporting-api/errors).

## Next steps

* [Quickstart](/reporting-api/quickstart): create, poll, and download your first report
* [Create and poll a run](/reporting-api/create-and-poll): retry details and polling patterns
* [API reference](/api-reference/report-runs/create-report-run): full endpoint and schema reference


## Related topics

- [API Reference Overview](/api-reference/overview.md)
- [Reporting API Quickstart](/reporting-api/quickstart.md)
- [Reporting API Errors and Troubleshooting](/reporting-api/errors.md)
