Get shipping rates
AI agents: read /llms.txt; add .md to any page URL. This page as Markdown: /reference/shipping-rates-and-estimates/v2-shipment-rate-goshippo.md. Index of every page and the rules for every call: /llms.txt. Guides and concepts in one file: /llms-full.txt. OpenAPI: /openapi.json.
POST/
Asks Shippo for the rates to ship parcels between two addresses. Nothing is bought, and nothing is saved in YoPrint. Shippo keeps the request as a Shippo shipment in your Shippo account.
The reply is a trimmed copy of Shippo's shipment, without the usual success/data envelope, with HTTP 201. It has only these keys: object_id, status, rates, messages, address_from, address_to, parcels, extra (only reference_1, billing, insurance, signature_confirmation, saturday_delivery), shipment_date and carrier_accounts. The top-level object_id is the Shippo shipment, and each rates[].object_id is a rate you can buy with Buy a shipping label.
Options you want on the label (insurance, signature, Saturday delivery, third-party billing, references) go in extra here: the purchase can't change them.
Where the addresses come from. Rates are not tied to the YoPrint shipment: you send both addresses and the parcels yourself, YoPrint doesn't compare them with the shipment, and the label is bought for the rate's addresses and parcels. Build them the way the web app does. A shipment returns only ids (customer_id, shipping_address_id, receiver_contact_id, customer_profile_id), so read the records behind them:
- Ship To (
address_to): Get a customer address,GET /v1/api/store/{team_slug}/customer/{customer_id}/address/{shipping_address_id}; and, when the shipment has one, the receiver contact with Get a contact by id,GET /v1/api/store/{team_slug}/contact/{receiver_contact_id}. - Ship From (
address_from): whencustomer_profile_idis set, the brand profile with Get a brand profile,GET /v1/api/store/{team_slug}/customer/{customer_id}/profile/{customer_profile_id}(itsaddressis the Ship From address); otherwise one of your company locations (List company locations), with your team'semailandphonefrom Get your company details.
| Shippo field | address_to |
address_from |
|---|---|---|
name |
receiver contact first_name + last_name; else the address label; else the customer's name |
brand profile company_name; else the location label |
company |
the customer's name when it differs from name; empty when the shipment has a brand profile |
empty |
street1 |
address address1 |
address address1 |
street2 |
address address2 |
address address2 |
city |
address city |
address city |
state |
address state_code (or state when there is no code) |
the same |
zip |
address postcode |
address postcode |
country |
address country_code (or country) |
the same |
email |
receiver contact email |
brand profile email; else the team's email |
phone |
receiver contact phone |
brand profile phone; else the team's phone |
Shippo needs name, street1, city, state, zip and country on both; company locations have no name or phone of their own.
Money here: a rate's amount is a decimal string in currency ("12.40"); parse it as a decimal. After purchase, each package's charges is that amount cut to 3 decimal places, in thousandths, an older encoding (12400 is 12.40; usually a whole number of thousandths; a finer value comes back as a fractional number, or as an exact decimal string with X-Yoprint-Decimal-Format: exact-v1). On a multi-parcel label, every package repeats the rate's full amount: read the master package's value and don't add the packages up. See Money and quantities.
The order of calls:
- Optional: List Shippo carrier accounts, to limit rates to some of your accounts.
- Get shipping rates with the addresses and parcels. Note the top-level
object_id(the Shippo shipment) and the chosen rate'sobject_id(rates[].object_id). - Optional: Save a shipping estimate on the YoPrint shipment, to keep the quote.
- Buy a shipping label with the rate's
object_idasrate_id. This is the only step that costs money. - Print: Download labels as one PDF. Track: Get live tracking for a package.
Business rules
- Both addresses need
name,street1,city,state,zipandcountry. - Each parcel needs its dimensions and weight (at least 0.01) and their units.
- Use
carrier_accounts(plural). A singularcarrier_accountis read only when the plural is missing and is not checked.
Side effects
- Calls Shippo, which stores a Shippo shipment in your Shippo account. Nothing is bought or saved in YoPrint.
Path parameters
Your team slug, shown as Team ID next to your API key in Profile.
- Example
your-team
- Example
Request body
application/json, required.
Where the parcels ship from.
Child fields (11)
- At most 255 characters
ISO country code, for example
US. Upper-cased for you.- At most 50 characters
- At most 255 characters
State or province code. Upper-cased for you.
- At most 50 characters
- At most 255 characters
- At most 20 characters
companystring- At most 255 characters
emailstring (email)- At most 255 characters
phonestring- At most 20 characters
street2string- At most 255 characters
validatebooleanPassed to Shippo: ask it to validate the address.
Where they go.
- Same fields as
address_from.
- Same fields as
One entry per box. More than one makes a multi-parcel shipment, bought as one rate.
- At least 1 item
Fields of each item (8)
- One of:
"cm","in","ft","m","mm","yd"
- One of:
- Minimum 0.01
A plain number, or a numeric string (the web app sends
"12"). At least 0.01.- Minimum 0.01
- One of:
"g","kg","lb","oz"
- One of:
A plain number or numeric string, in
mass_unit.- Minimum 0.01
- Minimum 0.01
extraobjectChild fields (1)
insuranceobjectInsurance.
amountandcurrencyare required when you send it.Child fields (4)
templatestringA Shippo carrier parcel template token. The dimensions and weight are still required.
- At most 255 characters
asyncbooleanLeave false. With
trueShippo answers before it has rates; the only later read is Save a shipping estimate with the reply'sobject_id, which reads the shipment back with its rates.- Default
false
- Default
carrier_accountsarray of stringsCarrier account
object_ids to rate. Omit to rate every active account.extraobject | nullLabel options, passed on to Shippo. Other Shippo
extrakeys are passed on unchecked.Child fields (6)
billingobjectBill the shipment to another carrier account (third party or recipient).
account,countryandtypeare required when you send it.Child fields (5)
accountstring- At most 255 characters
countrystring- Exactly 2 characters
participation_codestring- At most 255 characters
typestring- At most 50 characters
zipstring- At most 20 characters
insuranceobjectInsurance.
amountandcurrencyare required when you send it.- Same fields as
parcels[].extra.insurance.
- Same fields as
reference_1string- At most 255 characters
reference_2string- At most 255 characters
saturday_deliverybooleansignature_confirmationstring- One of:
"STANDARD","ADULT","CERTIFIED","INDIRECT","CARRIER_CONFIRMATION"
- One of:
shipment_datestring (date-time) | nullWhen you plan to hand the parcels over. Defaults to now.
Response
201A trimmed copy of the Shippo shipment with its rates, without the YoPrint envelope.
The Shippo shipment. Send it as
goshippo_shipment_idto save an estimate.Fields of each item (19)
amountstringamount_localstringarrives_bystring | nullattributesarray of stringsShippo's tags, for example
CHEAPEST.carrier_accountstringcurrencystringcurrency_localstringduration_termsstring | nullestimated_daysinteger | nullincluded_insurance_pricestring | nullmessagesarray of objectsobject_createdstringobject_idstringThe rate id. Send it as
rate_idto buy this label.object_updatedstringproviderstringprovider_image_200stringprovider_image_75stringA URL of the carrier logo.
servicelevelobjectExactly these four keys; null when Shippo sends no service level.
Child fields (4)
extended_tokenstringnamestringtermsstringtokenstring
shipmentstringThe Shippo shipment this rate belongs to.
address_fromobjectExactly
name,company,city,country,email,phone,state,street1,street2,zip; empty strings for what Shippo leaves out.address_toobjectThe same ten keys as
address_from.carrier_accountsarray of stringsextraobject | nullmessagesarray of objectsparcelsarray of objectsshipment_datestring | nullstatusstringShippo's status. With
ERROR, or no rates, readmessages.- One of:
"SUCCESS","QUEUED","ERROR"
- One of:
Errors
401The API key is missing or wrong (
unauthenticated).403You are not allowed to do this.
api_access_not_in_plan: your team's plan doesn't include API access (Pro and above, with an active subscription or trial), so every request answers this until the team upgrades. When your role lacks the permission the operation needs, the body is only{"message": "Insufficient Permission"}. Other refusals use the error envelope, withunauthorizedoruser_is_not_authorized.404Not found.
page_not_found: the team slug is unknown, you are not a member of the team, or an id in the path is not one of this team's.code: null, with a message that starts "No query results for": there is no record with that id.422The request was refused and changed nothing.
validation_failedlists what to fix inerror.fields; other codes name a business rule, explained inerror.message. A few checks answer with only{"message": "..."}. An operation that calls another service (a payment provider, a carrier, an accounting app) can answerconnect_timeout("Please retry again") when that service does not answer in time: the change may or may not have happened there, so read the record back before you retry.- When
- A required address or parcel field is missing, a unit isn't in the list, or an
extraoption is out of range (validation_failed). - Fix
- Fix the fields listed in
error.fields. - When
- Shippo isn't connected or is disabled (
goshippo_not_enabled). - Fix
- Connect Shippo in the web app first.
500A business rule refused the request (see the operation's errors), or something failed inside YoPrint. Refusals use the error envelope with a code such as
action_not_allowed; an unexpected failure answers{"message": "Server Error"}. Repeating a refusal gets the same answer; after an unexpected failure, read the record back before you retry a change.- When
- Shippo refused the request or could not be reached. Shippo errors are not translated into 4xx replies.
- Fix
- Check the addresses, parcels and ids, then retry once. Do not loop.
Notes
- A 201 can still carry no rates: check
status,messagesand each rate'smessages. - Rates are quotes from Shippo. YoPrint doesn't record how long Shippo keeps a rate buyable: buy soon after rating, and if the purchase is refused, rate again.
Related
- POSTList Shippo carrier accounts
/v2/ api/ store/ {team_slug}/ v2/ carrier_account/ goshippo - POSTSave a shipping estimate
/v2/ api/ store/ {team_slug}/ v2/ shipment/ {hash_id}/ shipment_estimate/ goshippo - POSTBuy a shipping label (charges your Shippo account)
/v2/ api/ store/ {team_slug}/ v2/ shipment/ {hash_id}/ label/ goshippo - GETGet a shipment
/v2/ api/ store/ {team_slug}/ v2/ shipment/ {unique_key} - GETGet a customer address
/v1/ api/ store/ {team_slug}/ customer/ {hash_id}/ address/ {id} - GETGet a contact by id
/v1/ api/ store/ {team_slug}/ contact/ {id} - GETGet a brand profile
/v1/ api/ store/ {team_slug}/ customer/ {hash_id}/ profile/ {id} - GETList company locations
/v1/ api/ store/ {team_slug}/ setting/ location - GETGet your company details
/v1/ api/ store/ {team_slug}/ setting/ detail
