Shipments

Shipments are the core resource in the Corvo API. A shipment represents a PDF document being printed, packaged, and delivered to a recipient. You always create shipments as drafts to compare rates, then explicitly purchase with the /buy endpoint.

Shipment object

Core fields

NameTypeRequiredDescription
idstring (UUID)YesShipment ID.
statusstringYesCurrent shipment status.
shipment_namestring | nullYesOptional human-readable label you supplied during creation.
page_countintegerYesValidated PDF page count.
print_optionsobjectYesCurrent print settings (`color`, `duplex`).
shipping_optionsobjectYesCurrent shipping settings (`delivery_confirmation`, `certified_mail`, `return_receipt`).
to_addressobjectYesRecipient address after verification or correction. Includes `verified` and `residential`.
from_addressobjectYesReturn address used for the shipment. May remain `verified: false` if soft verification could not confirm it.
tagsarrayYesArray of `{ id, name }` tag objects.
created_atdatetimeYesShipment creation timestamp.

Delivery and fulfillment fields

NameTypeRequiredDescription
carrierstring | nullYesCarrier selected for the purchased shipment, or `null` while still a draft.
servicestring | nullYesService level selected for the purchased shipment, or `null` while still a draft.
tracking_numberstring | nullYesTracking number once postage has been purchased.
tracking_urlstring | nullYesCarrier tracking URL when available.
selected_quote_idstring | nullYesChosen draft quote ID after purchase, if Corvo can map it back to the stored quote.
shipped_atdatetime | nullYesTimestamp set when Corvo hands the package to the carrier.
delivered_atdatetime | nullYesCarrier-confirmed delivery time when available.
signer_namestring | nullYesSigner name for certified-mail delivery events when available.
usps_accepted_atdatetime | nullYesUSPS acceptance timestamp for certified-mail workflows when available.
scan_form_idstring | nullYesInternal SCAN form reference when applicable to USPS workflows.

Pricing fields

NameTypeRequiredDescription
postage_cost_centsintegerYesRaw carrier postage cost stored on the purchased shipment.
postage_markup_centsintegerYesMarkup applied on top of raw postage for purchased shipments.
envelope_fee_centsintegerYesPer-shipment handling fee.
page_fee_centsintegerYesBlack-and-white page fee component.
page_fee_color_centsintegerYesColor surcharge component.
tax_amount_centsintegerYesTax charged on the shipment, if any.
total_charged_centsintegerYesTotal charged amount in cents.

Optional fields

NameTypeRequiredDescription
document_preview_urlstring | nullYesShort-lived preview URL for the uploaded PDF, when Corvo can generate one.
document_filenamestring | nullYesStored filename for the PDF.
eventsarray | undefinedNoOrdered shipment event timeline. Included on shipment detail responses.
ratesarray | undefinedNoDraft quote array. Included on shipment creation and on detail responses while the shipment is still `draft` or `payment_failed`.
quotes_expire_atdatetime | undefinedNoShared expiry timestamp for the returned draft quotes.
mailing_recordsobject | undefinedNoMailing-record state for certified-mail shipments, including acceptance, delivery, return-receipt, and retention details.
shipped_data_expires_atdatetime | nullNoCanonical shipped-data purge timestamp. Snapshot when the shipment first becomes shipped and used for warnings and purge scheduling.
artifactsarray | undefinedNoDownloadable evidence artifacts for shipment detail responses, including Corvo-generated summary and bundle entries plus retained carrier-backed files.

Rate quote object

NameTypeRequiredDescription
quote_idstring (UUID)YesQuote ID to pass to `/buy`.
carrierstringYesRaw EasyPost carrier value.
servicestringYesRaw EasyPost service value.
postage_centsintegerYesDraft quote postage including Corvo markup.
handling_fee_centsintegerYesHandling fee component.
printing_fee_centsintegerYesPrinting fee component.
color_surcharge_centsintegerYesColor surcharge component.
total_centsintegerYesTotal quoted charge in cents.
delivery_daysinteger | nullYesCarrier delivery-days estimate.
delivery_datedatetime | nullYesCarrier delivery-date estimate.
delivery_date_guaranteedbooleanYesWhether the carrier marked the delivery date as guaranteed.

Shipment event object

NameTypeRequiredDescription
idstringYesEvent ID.
statusstringYesNew shipment status for the event.
from_statusstring | nullYesPrevious status when available.
messagestring | nullYesHuman-readable event message.
actorstring | nullYesActor such as `user:<id>` or `webhook:printnode`.
metadataobject | nullYesEvent metadata payload when present.
created_atdatetimeYesEvent timestamp.

Mailing-record object

NameTypeRequiredDescription
acceptanceobjectYesAcceptance workflow state, including whether postage was purchased, whether a SCAN form/tender event exists, and whether USPS acceptance has been recorded.
deliveryobjectYesLatest carrier delivery state, including delivered, attempted, signer, and return-to-sender timestamps when available.
return_receiptobjectYesReturn-receipt request state and any linked retained return-receipt artifact.
retentionobjectYesSnapshot-driven shipped retention details, including the canonical purge date used for original PDFs and retained evidence.

Artifact object

NameTypeRequiredDescription
idstringYesArtifact identifier.
kindstringYesArtifact type such as `mailing_record_summary_pdf` or `carrier_scan_form_pdf`.
sourcestringYesArtifact source, for example `corvo` or `easypost`.
provenancestringYesOne of `carrier_native`, `carrier_event`, or `corvo_generated`.
statusstringYesArtifact state such as `available`, `failed`, or `expired`.
filenamestring | nullYesSuggested download filename.
content_typestring | nullYesArtifact content type when known.
available_atdatetime | nullYesWhen the artifact became available.
expires_atdatetime | nullYesWhen the artifact is scheduled to expire, if known.
download_urlstring | nullYesAuthenticated Corvo download path for the artifact.

Create a draft shipment

POST/api/v1/shipments

Create a draft shipment and return live quotes. Purchase is always a separate `/buy` call.

Top-level request body

NameTypeRequiredDescription
document_keystringNoPreviously uploaded document key.
documentstringNoBase64-encoded PDF. Useful for simple server-to-server flows.
shipment_namestringNoOptional human-readable label for your own dashboard and reporting.
to_addressobjectYesRecipient address object.
from_addressobjectNoReturn address object. If omitted, Corvo uses the organization default return address from the dashboard.
print_optionsobjectYesPrint settings object.
shipping_optionsobjectNoOptional quote filters and USPS options.
tagsstring[]NoOptional array of tag names. Maximum 50.

Address object

NameTypeRequiredDescription
namestringNoFull name. At least one of `name` or `company` is required.
companystringNoCompany name. At least one of `name` or `company` is required.
street1stringYesStreet address line 1.
street2stringNoStreet address line 2.
citystringYesCity.
statestringYesState or province.
zipstringYesPostal code.
countrystringNoTwo-letter country code. Defaults to "US".
phonestringNoPhone number.
emailstringNoEmail address.

Print options

NameTypeRequiredDescription
colorbooleanYesPrint in color when `true`.
duplexbooleanYesPrint double-sided when `true`.

Shipping options

NameTypeRequiredDescription
carrierstringNoOptional carrier filter. Use the raw EasyPost carrier value, for example `USPS`, `FedEx`, or `UPS`.
servicestringNoOptional service filter. Requires `carrier` and must use the raw EasyPost service value.
delivery_confirmationstringNoOptional EasyPost delivery-confirmation value such as `SIGNATURE`, `ADULT_SIGNATURE`, or `SIGNATURE_RESTRICTED`.
certified_mailbooleanNoSet `true` to request USPS Certified Mail.
return_receiptbooleanNoSet `true` only when `certified_mail` is also `true`.
Shell
curl -X POST https://corvo.to/api/v1/shipments \
  -H "Authorization: Bearer $CORVO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "document_key": "documents/org-id/notice.pdf",
    "shipment_name": "Eviction Notice",
    "to_address": {
      "name": "Jordan Reed",
      "street1": "123 Main St",
      "city": "Austin",
      "state": "TX",
      "zip": "78701"
    },
    "print_options": {
      "color": false,
      "duplex": true
    },
    "shipping_options": {
      "certified_mail": true,
      "return_receipt": true
    }
  }'
Response201Draft shipment
{
  "data": {
    "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "status": "draft",
    "shipment_name": "Eviction Notice",
    "page_count": 4,
    "print_options": {
      "color": false,
      "duplex": true
    },
    "shipping_options": {
      "delivery_confirmation": null,
      "certified_mail": true,
      "return_receipt": true
    },
    "to_address": {
      "name": "Jordan Reed",
      "company": null,
      "street1": "123 Main St",
      "street2": null,
      "city": "Austin",
      "state": "TX",
      "zip": "78701",
      "country": "US",
      "phone": null,
      "email": null,
      "verified": true,
      "residential": true
    },
    "from_address": {
      "name": "Acme Property Management",
      "company": null,
      "street1": "500 Congress Ave",
      "street2": null,
      "city": "Austin",
      "state": "TX",
      "zip": "78701",
      "country": "US",
      "phone": null,
      "email": null,
      "verified": true,
      "residential": false
    },
    "tags": [
      {
        "id": "tag_01",
        "name": "evictions"
      }
    ],
    "created_at": "2026-03-09T15:00:00.000Z",
    "rates": [
      {
        "quote_id": "quote_01",
        "carrier": "USPS",
        "service": "Priority",
        "postage_cents": 855,
        "handling_fee_cents": 300,
        "printing_fee_cents": 100,
        "color_surcharge_cents": 0,
        "total_cents": 1255,
        "delivery_days": 2,
        "delivery_date": "2026-03-11T00:00:00.000Z",
        "delivery_date_guaranteed": false
      }
    ],
    "quotes_expire_at": "2026-03-09T15:30:00.000Z"
  }
}
Response404Unknown document key
{
  "error": {
    "message": "Document not found or does not belong to this organization",
    "code": "DOCUMENT_NOT_FOUND"
  }
}

List shipments

GET/api/v1/shipments

List shipments for the authenticated organization.

Query parameters

NameTypeRequiredDescription
statusstringNoOptional shipment status filter.
tagstringNoOptional tag-name filter.
limitintegerNoResults per page. Defaults to 20 and maxes at 100.
cursorstring (UUID)NoPagination cursor returned as `next_cursor` from the previous page.
date_fromdate | datetimeNoStart boundary. Accepts `YYYY-MM-DD` or an ISO 8601 datetime with offset.
date_todate | datetimeNoEnd boundary. Accepts `YYYY-MM-DD` or an ISO 8601 datetime with offset. Date-only values are treated as end-of-day UTC.
Shell
curl "https://corvo.to/api/v1/shipments?status=shipped&tag=evictions&limit=10" \
  -H "Authorization: Bearer $CORVO_API_KEY"
Response200Shipment page
{
  "data": [
    {
      "id": "ship_01",
      "status": "shipped",
      "shipment_name": "Eviction Notice",
      "page_count": 4,
      "carrier": "USPS",
      "service": "Priority",
      "tracking_number": "9405511899223033005084",
      "tracking_url": "https://tools.usps.com/go/TrackConfirmAction?tLabels=9405511899223033005084",
      "total_charged_cents": 1255,
      "created_at": "2026-03-09T15:00:00.000Z",
      "shipped_at": "2026-03-10T13:22:00.000Z"
    }
  ],
  "has_more": true,
  "next_cursor": "ship_01"
}
Response400Invalid filter
{
  "error": {
    "message": "Invalid option: expected one of ...",
    "code": "VALIDATION_ERROR"
  }
}

Retrieve a shipment

GET/api/v1/shipments/{id}

Fetch the current state of a single shipment.

Path parameters

NameTypeRequiredDescription
idstring (UUID)YesShipment ID.
Shell
curl https://corvo.to/api/v1/shipments/f47ac10b-58cc-4372-a567-0e02b2c3d479 \
  -H "Authorization: Bearer $CORVO_API_KEY"
Response200Shipment detail
{
  "data": {
    "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "status": "queued",
    "carrier": "USPS",
    "service": "Priority",
    "tracking_number": "9405511899223033005084",
    "tracking_url": "https://tools.usps.com/go/TrackConfirmAction?tLabels=9405511899223033005084",
    "total_charged_cents": 1255,
    "created_at": "2026-03-09T15:00:00.000Z",
    "shipped_at": null,
    "events": [
      {
        "id": "evt_01",
        "status": "payment_pending",
        "from_status": "draft",
        "message": "Payment initiated for draft shipment",
        "actor": "user:4c1b8b16-2e4f-4de0-9ad5-e0ec0f16dbe8",
        "metadata": null,
        "created_at": "2026-03-09T15:00:04.000Z"
      }
    ]
  }
}
Response404Shipment not found
{
  "error": {
    "message": "Shipment not found",
    "code": "SHIPMENT_NOT_FOUND"
  }
}

Buy a draft shipment

POST/api/v1/shipments/{id}/buy

Charge the organization card on file and buy the selected draft quote.

Path parameters

NameTypeRequiredDescription
idstring (UUID)YesShipment ID.

Request body

NameTypeRequiredDescription
quote_idstring (UUID)YesDraft quote ID returned by shipment creation.
Shell
curl -X POST https://corvo.to/api/v1/shipments/f47ac10b-58cc-4372-a567-0e02b2c3d479/buy \
  -H "Authorization: Bearer $CORVO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"quote_id":"quote_01"}'
Response200Shipment purchased
{
  "data": {
    "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "status": "queued",
    "carrier": "USPS",
    "service": "Priority",
    "total_charged_cents": 1255,
    "tracking_number": "9405511899223033005084",
    "tracking_url": "https://tools.usps.com/go/TrackConfirmAction?tLabels=9405511899223033005084"
  }
}
Response400No payment method on file
{
  "error": {
    "message": "No payment method on file. Please add a card before creating shipments.",
    "code": "NO_PAYMENT_METHOD"
  }
}

Cancel a shipment

POST/api/v1/shipments/{id}/cancel

Cancel a shipment before terminal fulfillment.

Path parameters

NameTypeRequiredDescription
idstring (UUID)YesShipment ID.
Shell
curl -X POST https://corvo.to/api/v1/shipments/f47ac10b-58cc-4372-a567-0e02b2c3d479/cancel \
  -H "Authorization: Bearer $CORVO_API_KEY"
Response200Shipment cancelled
{
  "data": {
    "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "status": "cancelled"
  }
}
Response409Cannot cancel from current status
{
  "error": {
    "message": "Invalid status transition from \"shipped\" to \"cancelled\"",
    "code": "INVALID_STATUS_TRANSITION"
  }
}