{"openapi":"3.1.0","info":{"title":"VeloShip API","version":"1.0.0","description":"Ship with FedEx and other carriers: quote rates, buy labels one at a time or in bulk, track packages, and protect orders.\n\n**Using an AI assistant?** Point it at [/llms.txt](/llms.txt) (an index of markdown guides; [/llms-full.txt](/llms-full.txt) has everything in one file) and install the [VeloShip agent skill](/skills/veloship/SKILL.md) so it integrates correctly the first time. The spec you are reading is also at [/openapi.json](/openapi.json).\n\n**Building on Convex?** The [Convex component guide](/docs/convex/) covers quoting, buying, batching and tracking from Convex functions, with the results mirrored into reactive tables.\n\n## Quickstart\n\nBuy a test label in under five minutes. Sign up at `/admin/signup` (when sign-up is open) and copy the test key it shows once, or create one under **API keys**. Test keys (`sk_test_…`) use mock carriers, so nothing is charged and nothing is shipped.\n\n```sh\nexport VELOSHIP_KEY=sk_test_…\ncurl -s https://ship.vprev.dev/v1/shipments \\\n  -H \"Authorization: Bearer $VELOSHIP_KEY\" -H \"Idempotency-Key: $(uuidgen)\" -H \"Content-Type: application/json\" \\\n  -d '{ \"service\": \"FEDEX_GROUND\", \"parcel\": { \"weight\": 16 },\n        \"from_address\": { \"name\": \"Warehouse\", \"street1\": \"100 Main St\", \"city\": \"Memphis\", \"state\": \"TN\", \"zip\": \"38118\", \"country\": \"US\", \"phone\": \"9015551234\" },\n        \"to_address\": { \"name\": \"Jane Doe\", \"street1\": \"1 Market St\", \"city\": \"San Francisco\", \"state\": \"CA\", \"zip\": \"94105\", \"country\": \"US\", \"phone\": \"4155551234\" } }' \\\n  | jq -r .label_url\n```\n\nThat prints the label URL; open it with the same `Authorization` header. To go live, connect a carrier account, verify your email and use an `sk_live_` key. The admin's **Today** page tracks these steps.\n\n**Authentication.** Integrations send an API key as `Authorization: Bearer <key>`; the key belongs to one organization and sees only its data. `sk_test_` keys work on separate test data with mocked carriers, so nothing is charged. The admin signs in with a session cookie instead; its requests run with the member's role and active organization, and state-changing ones must come from the same origin.\n\n**Retries.** Send an `Idempotency-Key` header on every `POST`. Retrying with the same key returns the first response instead of buying twice.\n\n**Money** is a decimal string in dollars, like `\"12.34\"`. **Weights** are in ounces.\n\n**Shipping rules** decide things for you: require a signature over $100, never quote Ground to Hawaii, block PO boxes, pick the cheapest USPS rate under a pound. They run on every quote, shipment and batch order, and each response says which rules matched (`applied_rules`) and which rates they removed (`excluded_rates`). Send `apply_rules: false` to skip them. See **Shipping rules**.\n\n**Errors** look like `{ \"error\": { \"code\", \"message\", \"details\" } }`.\n\n**Testing.** With an `sk_test_` key you can make the mocked carriers misbehave. Send `VeloShip-Scenario: <name>` (add `@<carrier>` to limit it to one carrier, e.g. `carrier_down@ups`), or put `__scenario:<name>` in `to_address.street2`. The header wins over the token. Live keys ignore both. Scenarios: `address_invalid`, `address_suite_missing`, `residential`, `commercial`, `rates_slow`, `carrier_down`, `carrier_rate_limited`, `no_rates`, `purchase_timeout`, `purchase_rejected`, `customs_rejected`, `auth_rejected`, `labels_not_enabled`, `charge_mismatch`, `void_rejected`, `delivered_fast`, `exception_then_delivered`, `return_to_sender`, `lost`. Each one's trigger, effect and expected errors are in the Testing guide (docs/testing.md); to exercise your webhook endpoint, call `POST /v1/webhooks/{id}/test`. Every request is recorded and can be inspected with `GET /v1/request_logs`."},"servers":[{"url":"/","description":"This server"}],"security":[{"apiKey":[]},{"sessionCookie":[]}],"tags":[{"name":"Rates","description":"Prices before an order exists."},{"name":"Shipments","description":"Create shipments, buy and void labels."},{"name":"Batches","description":"Buy up to 100 labels at once and print them as one file."},{"name":"Reports","description":"Spend, savings and what needs attention."},{"name":"Drafts","description":"Unfinished Ship forms saved on the server, so they follow you between devices."},{"name":"Package protection","description":"Your own guarantee for lost, stolen or damaged orders, and its claims. Not insurance."},{"name":"Carriers","description":"The carriers you can ship with, and the carrier accounts that quote and buy for you."},{"name":"Tracking","description":"Package tracking, refreshed automatically. The carrier is detected from the tracking number."},{"name":"Public tracking","description":"What the recipient sees. Authenticated by an unguessable link instead of an API key."},{"name":"Addresses","description":"Saved and verified addresses."},{"name":"Settings","description":"Default from address, parcel presets, protection pricing, recipient emails and tracking page branding."},{"name":"Shipping rules","description":"Conditions and actions that run on every quote, shipment and batch order: require a signature over $100, drop Ground to Hawaii, block PO boxes, pick the cheapest USPS rate under a pound. Test and live mode keep separate rules."},{"name":"Printing","description":"VeloShip Print: labels, packing slips, packing lists and invoices sent to printers next to your packing bench through the print agent, with no print dialog."},{"name":"Webhooks","description":"Events are POSTed to your HTTPS URL as an `Event` object (see Models). Check the `X-Webhook-Signature` header (`t=<unix>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">`) with the webhook's secret before trusting it. Respond with any 2xx within 10 seconds; anything else is retried up to 8 times over about two hours. Delivery is at least once, so deduplicate on the event `id`."},{"name":"Account","description":"API keys, their scopes and limits, the audit log, and the request log."},{"name":"Organization","description":"The organization's members, invitations and roles. Roles map onto scopes: `viewer` reads, `member` ships, `admin` also manages settings, webhooks, keys and members, `owner` adds organization management."},{"name":"Sessions","description":"Sign-in for the admin. Sessions are HttpOnly cookies; the sign-in, sign-out and passkey endpoints live under `/api/auth/*` (Better Auth)."},{"name":"Onboarding","description":"The getting-started checklist for new organizations, worked out from real state."},{"name":"Billing","description":"Metered billing for live labels through Polar. Everything here is unavailable (`enabled: false`) until the server is configured for it, and the platform's own organization is never billed. Test mode is always free."},{"name":"Health","description":"Uptime checks."}],"paths":{"/v1/rules":{"get":{"tags":["Shipping rules"],"summary":"List rules","description":"Needs `rules:read` (every role). The organization's rules for this mode, in evaluation order, with warnings about overlaps and mistakes. `?include=stats` adds how often each rule matched the last 200 shipments.\n\nShipping rules say what should happen to a shipment when it matches a condition: \"when the order is over $100, require a signature\". They run top to bottom on every quote, shipment and batch order; every matching rule applies, and when two rules set the same thing the later one wins. Rules cost no carrier calls. Test and live mode keep separate rules. Send `apply_rules: false` on any request to skip them.\n\n**Precedence.** What you send beats rules that set the same thing: an `options.signature`, `options.declared_value`, `options.saturday_delivery`, `options.one_rate`, `protection`, a parcel preset or packaging, a `from_address`, or a specific `service`. Limits always apply: excluding carriers or services, `only_*`, `max_delivery_days`, `max_price` and `block` can't be overridden by a request. If nothing survives, the call fails with `422 RULES.NO_RATE`, naming each rule and the rates it removed. A `max_price` with `if_none_left: \"relax\"` never causes that: when it would leave no rate it removes none, so caps can fall back (at most what the customer paid, else $3 more, else anything). `block` fails with `422 RULES.BLOCKED`.\n\n**What was decided** is returned as `applied_rules` (each matching rule and what it did), `excluded_rates` (what was removed and why) and `recommended_rate` on quotes, shipments, batch items and comparisons. The full guide, with recipes, is in docs/rules.md.","parameters":[{"name":"include","in":"query","required":false,"schema":{"description":"`stats` adds how often each rule matched the last 200 shipments","type":"string","enum":["stats"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuleList"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"}}},"post":{"tags":["Shipping rules"],"summary":"Create a rule","description":"Needs `rules:write` (owners and admins). Adds a rule (at `position`, default last). At most 50 per mode (`RULES.LIMIT`). Conditions are validated strictly: errors name the path, e.g. `when.all.0.op`. Every change is written to the audit log.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRule"},"example":{"name":"Signature on orders over $100","when":{"all":[{"field":"order.value","op":"gt","value":"100.00"}]},"then":[{"type":"set_signature","signature":"direct"}]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Rule"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/rules/{id}":{"get":{"tags":["Shipping rules"],"summary":"Get a rule","description":"Needs `rules:read` (every role). ","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Rule"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}},"patch":{"tags":["Shipping rules"],"summary":"Update a rule","description":"Needs `rules:write` (owners and admins). Send only what changes. `when` and `then` replace the whole condition or action list. `position` moves the rule.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRule"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Rule"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"422":{"$ref":"#/components/responses/E422"}}},"delete":{"tags":["Shipping rules"],"summary":"Delete a rule","description":"Needs `rules:write` (owners and admins). ","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/rules/reorder":{"post":{"tags":["Shipping rules"],"summary":"Reorder rules","description":"Needs `rules:write` (owners and admins). `rule_ids` lists every rule exactly once, first evaluated first. A list that doesn't match the current rules (someone added or deleted one) is refused with `409 RULES.CONFLICT`: reload and try again.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReorderRules"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuleList"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/rules/test":{"post":{"tags":["Shipping rules"],"summary":"Try rules on a sample (dry run)","description":"Needs `rules:read` (every role). Shows which rules match a sample request and why: every test in each condition with what the request had, the effects, and the request as the rules would change it. Give `input` (like `POST /v1/rates`, plus `reference`, `service` and `source`) or a `shipment_id` to replay a saved shipment's addresses, parcel and order. Pass `rules` to try unsaved edits instead of the saved rules. With `quote: true` (also needs `rates:read`) it quotes with the carriers (the mock ones in test mode) and returns the rates that survive, the ones removed and the recommended one. Nothing is saved or bought. Without `quote`, no carrier is called, so a destination's home-or-business classification is only known when the address says so.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRules"},"example":{"input":{"to_address":{"name":"Jane Doe","street1":"1 Kalakaua Ave","city":"Honolulu","state":"HI","zip":"96815","country":"US","phone":"8085551234"},"parcel":{"weight":40},"order":{"value":"180.00","tags":["fragile"],"shipping_method":"Expedited"}},"quote":true}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuleTestResult"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/rules/draft":{"post":{"tags":["Shipping rules"],"summary":"Describe a rule in English","description":"Needs `rules:write` (owners and admins). Turns a plain-English description (\"Anything to Hawaii or Alaska over 2 lb should go 2-day air, and add a signature if the order is over $150\") into draft rules. Nothing is saved: review the drafts, try them with `/v1/rules/test`, then create them. With `existing_rule_id` it edits that rule (\"also exclude USPS\"). Parts that can't be expressed come back in `unsupported`, loose wording in `assumptions`, and real ambiguity in `questions`. The text is sent to Anthropic's API together with your carrier services, preset names and rule names, never addresses or orders. Needs `ANTHROPIC_API_KEY` on the server (otherwise `503 RULES.AI_UNAVAILABLE`); limited per organization. `422 RULES.DRAFT_INVALID` means the model's output didn't validate even after one retry. The text isn't kept in the request log.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DraftRule"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuleDraft"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"422":{"$ref":"#/components/responses/E422"},"429":{"$ref":"#/components/responses/E429"},"502":{"$ref":"#/components/responses/E502"},"503":{"$ref":"#/components/responses/E503"}}}},"/v1/rules/copy_to_live":{"post":{"tags":["Shipping rules"],"summary":"Copy test rules to live","description":"Needs `rules:write` (owners and admins). Test mode only, and only for owners, admins and the root key (not API keys). Replaces the live rules with the test rules, as they are. Saved addresses differ between modes, so rules naming one (`set_from_address`, `from.address_id`) come back with an `address_missing` warning. Refuses (`422 RULES.COPY.EMPTY`) when there are no test rules and live has some. Written to the audit log with the names of what was copied.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuleList"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/print/jobs":{"post":{"tags":["Printing"],"summary":"Print something","description":"Needs `print:write` (members, admins, owners). Send exactly one source: `file_base64` (a PDF, PNG, JPEG or ZPL file up to 20 MB; images are placed on one page of `paper`), `shipment_id` (its label), `shipment_ids` (their labels as one job) or `batch_id` (every label the batch bought). Or upload the file as `multipart/form-data` with a `file` part and the other fields as form fields. Returns `201` with the queued job, or `200` with the earlier job when `idempotency_key` was used before.\n\nPrint labels, packing slips, packing lists and invoices on printers next to your packing bench, without a print dialog. Install the VeloShip Print agent on a Mac or Linux computer that has the printers (`POST /v1/print/pairing_codes` gives the one-line install command), and every job you create here is pushed to it within a second. Printers are shared by test and live mode; each job records the mode of the key that created it, and lists only show the caller's mode.\n\n**Routing.** A job prints on `printer_id` when given. Otherwise its `kind` picks a printer role at `location_id` (or the default location): `label` → the `label` printer, `slip` → the `slip` printer, falling back to the `label` printer, and `packing_list`, `invoice` and `document` → the `letter` printer. `role` overrides the kind's choice. When nothing matches the call fails with `422 PRINT.NO_PRINTER`, listing the roles that location has.\n\n**ZPL.** Send ZPL as `file_base64` (detected when it starts with `^` or `~`; otherwise add `content_type: \"application/x-zpl\"`), or print shipments and batches whose labels were bought as `ZPLII`. ZPL goes raw to printers whose `languages` include `zpl`: the station detects Zebra and ZPL drivers and raw queues, and you can mark any printer with `PATCH /v1/print/printers/{id}`. Anything else fails with `422 PRINT.FORMAT_NOT_SUPPORTED_BY_PRINTER`, as does a PDF sent to a ZPL-only printer.\n\n**Network printers.** `POST /v1/print/printers` adds a printer the station reaches over the network itself, with no printer queue: raw TCP to port 9100, or IPP.\n\n**Paper.** `paper: \"auto\"` takes the first page's size (4×6 or Letter), then the printer's role. A job whose paper the printer doesn't report fails with `422 PRINT.PAPER_MISMATCH`.\n\n**Delivery** is at least once, and a job the station already printed is never printed twice. A job the station doesn't confirm within its 2-minute lease goes back to the queue, and transient failures are retried with backoff; after 5 attempts it is `failed` and needs a person. Jobs nobody prints within a day become `expired`.\n\n**Health and failover.** Agents from 0.3.0 report each printer's `health` (`paper_out`, `paper_jam`, `cover_open`, `paused`, `offline`, `stuck`…). A printer that can't print gets no new jobs: they move to another healthy printer with the same role at the location (`failover`, on by default; `rerouted_from` and `reroute_reason` say so), or wait with a `waiting_reason` and fail after 15 minutes. Only jobs that certainly haven't started printing move, so a label never prints twice. Jobs sent to a `printer_id` never move.\n\n**Webhooks:** `print.job.done`, `print.job.failed`, `print.job.rerouted`, `print.printer.problem`, `print.printer.recovered`, `print.station.offline`, `print.station.online` and `print.station.updated`. Owners and admins are also emailed when a printer has a problem for 2 minutes or a station goes offline (see `/v1/print/settings`).\n\n**Agent updates.** Agents from 0.2.0 install signed releases by themselves, between jobs, when the station's `auto_update` is on (the default) or after `POST /v1/print/stations/{id}/update`. A station's `agent_update` says where it stands.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePrintJob"},"example":{"shipment_id":"shp_01a131ca1cec532ff358a581e16a","kind":"label","copies":1}},"multipart/form-data":{"schema":{"allOf":[{"$ref":"#/components/schemas/PrintJobOptions"},{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJob"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"413":{"$ref":"#/components/responses/E413"},"422":{"$ref":"#/components/responses/E422"}}},"get":{"tags":["Printing"],"summary":"List print jobs","description":"Needs `print:read` (every role). Newest first, in the caller's mode.","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["queued","sent","printing","done","failed","cancelled","expired"]}},{"name":"kind","in":"query","required":false,"schema":{"type":"string","enum":["label","slip","packing_list","invoice","document"]}},{"name":"printer_id","in":"query","required":false,"schema":{"type":"string","maxLength":64,"format":"starts_with","pattern":"^prn_.*"}},{"name":"station_id","in":"query","required":false,"schema":{"type":"string","maxLength":64,"format":"starts_with","pattern":"^pst_.*"}},{"name":"created_after","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"created_before","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"before_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"page_size","in":"query","required":false,"schema":{"default":20,"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"jobs":{"type":"array","items":{"$ref":"#/components/schemas/PrintJob"}},"has_more":{"type":"boolean"}},"required":["jobs","has_more"]}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/print/jobs/{id}":{"get":{"tags":["Printing"],"summary":"Get a print job","description":"Needs `print:read` (every role). ","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJob"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/print/jobs/{id}/cancel":{"post":{"tags":["Printing"],"summary":"Cancel a print job","description":"Needs `print:write` (members, admins, owners). Only while `queued` or `sent`; once the printer has it, `409 PRINT.JOB_NOT_CANCELLABLE`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJob"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"}}}},"/v1/print/jobs/{id}/reprint":{"post":{"tags":["Printing"],"summary":"Reprint a job","description":"Needs `print:write` (members, admins, owners). A new job with the same file, on the same printer or `printer_id`. `410 PRINT.FILE_EXPIRED` once the file is past retention.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReprintJob"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJob"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"410":{"$ref":"#/components/responses/E410"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/print/printers":{"get":{"tags":["Printing"],"summary":"List printers","description":"Needs `print:read` (every role). Every printer the organization's stations report, with its roles.","parameters":[{"name":"location_id","in":"query","required":false,"schema":{"type":"string","maxLength":64,"format":"starts_with","pattern":"^ploc_.*"}},{"name":"station_id","in":"query","required":false,"schema":{"type":"string","maxLength":64,"format":"starts_with","pattern":"^pst_.*"}},{"name":"role","in":"query","required":false,"schema":{"type":"string","enum":["label","slip","letter"]}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["idle","printing","offline","error"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"printers":{"type":"array","items":{"$ref":"#/components/schemas/Printer"}}},"required":["printers"]}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"}}},"post":{"tags":["Printing"],"summary":"Add a network printer","description":"Needs `print:manage` (owners and admins; API keys can't hold it). A printer the station reaches over its network by itself, without a printer queue on the computer. `raw9100` sends the job's bytes to the port (ZPL, or PDF for printers that take it); `ipp` sends an IPP Print-Job. The station checks it can connect before each heartbeat and reports `status`. Needs an agent with the `network` capability to print; `409 PRINT.PRINTER_EXISTS` when the station already has a printer at that address.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateNetworkPrinter"},"example":{"station_id":"pst_01a1…","name":"Zebra ZD421","host":"192.168.1.50","protocol":"raw9100","roles":["label"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Printer"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/print/printers/{id}":{"get":{"tags":["Printing"],"summary":"Get a printer","description":"Needs `print:read` (every role). ","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Printer"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}},"patch":{"tags":["Printing"],"summary":"Name a printer and give it roles","description":"Needs `print:manage` (owners and admins; API keys can't hold it). `roles` replaces the printer's roles; `default_for` makes it the location's default for those roles, taking over from another printer. A new printer that looks like a 4×6 label printer (or a Letter printer) gets that role automatically when its location has none. `languages` says whether it takes PDF, ZPL or both, overriding what the station detected. `host`, `port`, `protocol` and `path` change a network printer.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePrinter"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Printer"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"422":{"$ref":"#/components/responses/E422"}}},"delete":{"tags":["Printing"],"summary":"Remove a network printer","description":"Needs `print:manage` (owners and admins; API keys can't hold it). Its unfinished jobs fail. Printer queues the station reports can't be removed here (`409 PRINT.PRINTER_NOT_REMOVABLE`): remove them on the computer.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Removed"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"}}}},"/v1/print/printers/{id}/test":{"post":{"tags":["Printing"],"summary":"Print a test page","description":"Needs `print:write` (members, admins, owners). A VeloShip test page with the printer's name, the time, and a border and rulers to check alignment and scale.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintTestPage"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintJob"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/print/stations":{"get":{"tags":["Printing"],"summary":"List stations","description":"Needs `print:read` (every role). Paired computers that aren't revoked, with their printers.","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"stations":{"type":"array","items":{"$ref":"#/components/schemas/PrintStation"}}},"required":["stations"]}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}}},"/v1/print/stations/{id}":{"get":{"tags":["Printing"],"summary":"Get a station","description":"Needs `print:read` (every role). ","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintStation"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}},"patch":{"tags":["Printing"],"summary":"Rename, move, pause or resume a station","description":"Needs `print:manage` (owners and admins; API keys can't hold it). A paused station stays connected but gets no jobs; they wait in `queued`. `auto_update: false` stops the agent installing new releases by itself.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePrintStation"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintStation"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/print/stations/{id}/update":{"post":{"tags":["Printing"],"summary":"Update a station's agent now","description":"Needs `print:manage` (owners and admins; API keys can't hold it). Offers the latest release to the agent on its next heartbeat (within 30 seconds), even with `auto_update` off. It installs once nothing is printing and restarts; `print.station.updated` follows. `409 PRINT.UPDATE_UNAVAILABLE` when it is already up to date, nothing is published for its platform, or its agent is older than 0.2.0 and must be updated by running the install command once.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintStation"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"}}}},"/v1/print/stations/{id}/diagnostics":{"post":{"tags":["Printing"],"summary":"Ask a station for diagnostics","description":"Needs `print:manage` (owners and admins; API keys can't hold it). The agent (0.3.0 or later) builds a diagnostics bundle and uploads it within a minute when it is online; the request stays open for an hour. Returns `201` with the new request, or `200` with the one already open. A bundle holds the agent's version and uptime, the OS version, the agent's config without its station key, the login service's state, connection errors, the last 2,000 log lines, what CUPS reports (`lpstat -t`, each queue's options, the tail of CUPS's error log when readable), a summary of the agent's spool (states and the last 50 jobs, without titles or files), sleep settings, update state, DNS, TLS and clock checks against VeloShip, and free disk space. Before it leaves the computer the agent removes station keys, API keys, bearer tokens, passwords, the signatures of signed links, URL credentials, email addresses, phone numbers and street addresses. Bundles are deleted after 7 days.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintDiagnostics"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"}}},"get":{"tags":["Printing"],"summary":"List a station's diagnostics","description":"Needs `print:manage` (owners and admins; API keys can't hold it). Bundles and open requests from the last 7 days, newest first.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"diagnostics":{"type":"array","items":{"$ref":"#/components/schemas/PrintDiagnostics"}}},"required":["diagnostics"]}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/print/diagnostics/{id}/download":{"get":{"tags":["Printing"],"summary":"Download a diagnostics bundle","description":"Needs `print:manage` (owners and admins; API keys can't hold it). The bundle as gzipped JSON. `409 PRINT.DIAGNOSTICS_PENDING` while the station hasn't sent it; `404` once it is past its 7 days.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The gzipped JSON bundle","content":{"application/gzip":{"schema":{"type":"string","format":"binary"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"}}}},"/v1/print/stations/{id}/revoke":{"post":{"tags":["Printing"],"summary":"Revoke a station","description":"Needs `print:manage` (owners and admins; API keys can't hold it). Its key stops working at once, the agent is disconnected and its unfinished jobs fail. Pair the computer again to bring it back.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintStation"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/print/pairing_codes":{"post":{"tags":["Printing"],"summary":"Pair a station","description":"Needs `print:manage` (owners and admins; API keys can't hold it). A one-time code, valid for 15 minutes, and the command that installs the agent with it: paste `install_command` into Terminal on the computer next to the printer.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePairingCode"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintPairingCode"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/print/locations":{"get":{"tags":["Printing"],"summary":"List locations","description":"Needs `print:read` (every role). Where stations are. The first one is created as \"Main\" when the first station pairs.","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"locations":{"type":"array","items":{"$ref":"#/components/schemas/PrintLocation"}}},"required":["locations"]}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}},"post":{"tags":["Printing"],"summary":"Create a location","description":"Needs `print:manage` (owners and admins; API keys can't hold it). ","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePrintLocation"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintLocation"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/print/locations/{id}":{"patch":{"tags":["Printing"],"summary":"Rename a location, make it the default, or set failover","description":"Needs `print:manage` (owners and admins; API keys can't hold it). `failover: false` keeps jobs on their printer when it can't print; they wait for it instead.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePrintLocation"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintLocation"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/print/settings":{"get":{"tags":["Printing"],"summary":"Get printing alert settings","description":"Needs `print:read` (every role). Who is emailed when a printer has a problem or a station goes offline.","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintSettings"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}},"patch":{"tags":["Printing"],"summary":"Change printing alerts","description":"Needs `print:manage` (owners and admins; API keys can't hold it). Alerts are on by default and go to owners and admins. A printer problem is emailed once it has lasted `problem_minutes` (2), an offline station once it has been silent 5 minutes, within `business_hours` if set. Each problem is emailed once, and again when it is resolved.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePrintSettings"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintSettings"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/me":{"get":{"tags":["Account"],"summary":"Who am I","description":"The key's or user's ID, the mode, the organization the request runs in, and whether it's the root key.","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}}},"/v1/org":{"get":{"tags":["Organization"],"summary":"Get the organization","description":"The organization the key belongs to, or the signed-in member's active organization.","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Organization"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}},"patch":{"tags":["Organization"],"summary":"Rename the organization","description":"Needs `org:manage` (owners).","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenameOrganization"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Organization"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/org/members":{"get":{"tags":["Organization"],"summary":"List members","description":"Needs `members:manage` (owners and admins).","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"members":{"type":"array","items":{"$ref":"#/components/schemas/OrgMember"}}},"required":["members"]}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}}},"/v1/org/members/{id}":{"patch":{"tags":["Organization"],"summary":"Change a member's role","description":"Needs a signed-in session with `members:manage`. Admins can manage `member` and `viewer`; only owners can grant or change `owner` and `admin`. The last owner can't be demoted.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeMemberRole"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgMember"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"422":{"$ref":"#/components/responses/E422"}}},"delete":{"tags":["Organization"],"summary":"Remove a member","description":"Needs a signed-in session with `members:manage`. The last owner can't be removed.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Removed"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/org/invitations":{"get":{"tags":["Organization"],"summary":"List pending invitations","description":"Needs `members:manage`.","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"invitations":{"type":"array","items":{"$ref":"#/components/schemas/OrgInvitation"}}},"required":["invitations"]}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}},"post":{"tags":["Organization"],"summary":"Invite someone","description":"Needs a signed-in session with `members:manage`. Returns an `invite_url` to send to the invitee; when the Worker has an `EMAIL` binding it also emails it. Invitations expire after 7 days.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteMember"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgInvitation"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/org/invitations/{id}":{"delete":{"tags":["Organization"],"summary":"Cancel an invitation","description":"Needs a signed-in session with `members:manage`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Canceled"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/organizations":{"get":{"tags":["Organization"],"summary":"List every organization","description":"Root key only.","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"organizations":{"type":"array","items":{"$ref":"#/components/schemas/Organization"}}},"required":["organizations"]}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}},"post":{"tags":["Organization"],"summary":"Create an organization","description":"Root key only. Creates the organization and its first owner (and the owner's account when `owner.email` is new). Self-service organization creation exists only when `ALLOW_SIGNUP` is on.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganization"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Organization"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/bootstrap":{"post":{"tags":["Organization"],"summary":"Create the first owner","description":"Root key only, and only once: makes the first owner of the organization that existed before accounts (VeloPep Labs), so nobody can claim it by signing up first. Refused with `BOOTSTRAP.ALREADY_DONE` after that. Send `X-Org-Id` to target another organization that has no owner.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Bootstrap"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"user_id":{"type":"string"},"organization_id":{"type":"string"}},"required":["user_id","organization_id"]}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"422":{"$ref":"#/components/responses/E422"}}}},"/api/session":{"get":{"tags":["Sessions"],"summary":"Current session","description":"Who is signed in, their organizations and role, and what sign-in options are on. Always 200; `authenticated` says whether there is a session.","security":[],"parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Session"}}}}}}},"/config.json":{"get":{"tags":["Sessions"],"summary":"Public configuration","description":"What the static landing page needs to know: whether sign-up is open. Cached for a minute.","security":[],"parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"signup_open":{"type":"boolean"}},"required":["signup_open"]}}}}}}},"/api/signup":{"post":{"tags":["Sessions"],"summary":"Sign up","description":"Only when `ALLOW_SIGNUP` is on (otherwise 403 `SIGNUP.DISABLED`). Creates the account, an organization it owns and a test-mode API key (returned once), and signs in (sets the session cookie). New organizations are in test mode: live labels need a carrier account of their own, a verified email and, past the free allowance, a subscription. Refuses disposable and obviously invalid addresses, limits sign-ups per IP, and requires a Turnstile token (`turnstile_token`) when the server has `TURNSTILE_SECRET`. Same-origin browser requests only.","security":[],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Signup"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupResult"}}}},"409":{"$ref":"#/components/responses/E409"},"422":{"$ref":"#/components/responses/E422"},"429":{"$ref":"#/components/responses/E429"}}}},"/api/signup/organization":{"post":{"tags":["Sessions"],"summary":"Create another organization","description":"For a signed-in person with no organization (for example after Google sign-in) or one who wants another, up to `MAX_ORGS_PER_USER` (`ORG.LIMIT`). Returns the organization and its test key like sign-up does. Same-origin browser requests only.","security":[],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewOrganization"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupResult"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"422":{"$ref":"#/components/responses/E422"},"429":{"$ref":"#/components/responses/E429"}}}},"/api/verification/resend":{"post":{"tags":["Sessions"],"summary":"Resend the verification email","description":"For the signed-in person. 503 `EMAIL.NOT_CONFIGURED` when the server has no email binding. Same-origin browser requests only.","security":[],"parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"sent":{"type":"boolean"},"email_verified":{"type":"boolean"}},"required":["sent","email_verified"]}}}},"401":{"$ref":"#/components/responses/E401"},"429":{"$ref":"#/components/responses/E429"},"503":{"$ref":"#/components/responses/E503"}}}},"/v1/onboarding":{"get":{"tags":["Onboarding"],"summary":"Getting-started checklist","description":"Steps complete themselves from real state: a test key, a first call, a first test label, a verified email, a ship-from address, a carrier, a payment method (when billing is on) and a first live label.","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Onboarding"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}}},"/v1/billing":{"get":{"tags":["Billing"],"summary":"Plan and usage","description":"Usage for the current UTC month, the free allowance left, and the subscription's state. Needs `shipments:read` or `billing:manage`.","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Billing"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}}},"/v1/billing/checkout":{"post":{"tags":["Billing"],"summary":"Start a subscription","description":"Needs an owner signed in to the admin. Returns a Polar Checkout URL for the metered plan. 409 `BILLING.ALREADY_SUBSCRIBED` when one exists.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingSession"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"502":{"$ref":"#/components/responses/E502"}}}},"/v1/billing/portal":{"post":{"tags":["Billing"],"summary":"Open the billing portal","description":"Needs an owner signed in to the admin. Returns a Polar customer portal URL for payment methods, invoices and cancellation. 409 `BILLING.NO_CUSTOMER` before the first checkout.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingSession"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"502":{"$ref":"#/components/responses/E502"}}}},"/v1/organizations/{id}/verify_email":{"post":{"tags":["Organization"],"summary":"Verify an organization's owners","description":"Root key or an owner of the first organization. For deployments that can't send email: vouches for the email addresses of the organization's owners so it may buy live labels.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"verified_owners":{"type":"integer"}},"required":["verified_owners"]}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/api/invitations/{id}":{"get":{"tags":["Sessions"],"summary":"Look up an invitation","description":"What the invite link page shows. The ID is unguessable; repeated lookups from one IP are rate limited.","security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationPreview"}}}},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}}}},"/api/invitations/{id}/signup":{"post":{"tags":["Sessions"],"summary":"Create an account from an invitation","description":"Creates the account for the invited address, signs it in (sets the session cookie) and joins the organization. The only way to register while sign-up is closed. Same-origin browser requests only.","security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"organization_id":{"type":"string"}},"required":["organization_id"]}}}},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"422":{"$ref":"#/components/responses/E422"},"429":{"$ref":"#/components/responses/E429"}}}},"/api/invitations/{id}/accept":{"post":{"tags":["Sessions"],"summary":"Accept an invitation","description":"For someone already signed in with the invited address. Same-origin browser requests only.","security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"organization_id":{"type":"string"}},"required":["organization_id"]}}}},"401":{"$ref":"#/components/responses/E401"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/settings":{"get":{"tags":["Settings"],"summary":"Get settings","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Settings"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}},"patch":{"tags":["Settings"],"summary":"Update settings","description":"Fields you leave out are unchanged. `parcel_presets` and `protection` are replaced as a whole.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSettings"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Settings"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/settings/branding/logo":{"get":{"tags":["Settings"],"summary":"Get the logo","description":"The logo's bytes, served with `Content-Security-Policy: sandbox`. The tracking page serves it to recipients from its own URL.","parameters":[],"responses":{"200":{"description":"The logo","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string","format":"binary"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}},"put":{"tags":["Settings"],"summary":"Upload the logo","description":"Send the image itself as the body: PNG, JPEG, WebP or SVG, up to 512 KB. The type is read from the bytes. SVG with scripts, event handlers, `foreignObject`, entities or references to other files is refused (`BRANDING.LOGO_UNSAFE`). Replaces the current logo. Needs `settings:write`. Branding is shared by both modes, so test keys get `403 BRANDING.LIVE_ONLY`.","parameters":[],"requestBody":{"required":true,"content":{"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string","format":"binary"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Settings"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"413":{"$ref":"#/components/responses/E413"},"422":{"$ref":"#/components/responses/E422"}}},"delete":{"tags":["Settings"],"summary":"Remove the logo","description":"Needs `settings:write`. Live mode only.","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Settings"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}}},"/v1/carriers":{"get":{"tags":["Carriers"],"summary":"List carriers","description":"The carriers VeloShip can ship with and what each supports: services, packaging (including flat-rate boxes with their dimensions and weight limits), signature options, declared value, Saturday delivery, returns, label formats, the void window, address verification, reconciliation, push tracking and tracking-number patterns. `configured` says whether an enabled account exists. No secrets.","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"carriers":{"type":"array","items":{"$ref":"#/components/schemas/Carrier"}}},"required":["carriers"]}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}}},"/v1/carrier_accounts":{"get":{"tags":["Carriers"],"summary":"List carrier accounts","description":"Needs the `settings:write` scope. While no FedEx account has been created, the account made from the FEDEX_* secrets is listed as `ca_env_fedex`.","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"carrier_accounts":{"type":"array","items":{"$ref":"#/components/schemas/CarrierAccount"}}},"required":["carrier_accounts"]}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}},"post":{"tags":["Carriers"],"summary":"Add a carrier account","description":"Credentials are encrypted at rest and never returned. They need the `CARRIER_CREDENTIALS_KEY` secret on the server; without it, creating an account with credentials fails with `CARRIER_ACCOUNT.ENCRYPTION_NOT_CONFIGURED`. Creating a FedEx account replaces the implicit `ca_env_fedex` account for new quotes. Test-mode keys create accounts that use mock carriers.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCarrierAccount"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CarrierAccount"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/carrier_accounts/test":{"post":{"tags":["Carriers"],"summary":"Test carrier credentials before saving them","description":"Runs four checks and stores nothing: `auth` (an OAuth token), `rates` (a sample domestic quote), `address` (address validation, where the carrier offers it) and `labels` (whether label creation is enabled). The labels check never buys a label: FedEx validates a ship request, USPS mints a payment authorization token, and UPS has no safe probe so the check is `skipped`. A refusal such as FedEx's `FORBIDDEN.ERROR` is a `warn` with a hint, not a failure. Failed checks are results in a `200`, not errors. Needs the `settings:write` scope; limited to 6 per minute per organization.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestCarrierAccount"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectionTest"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"},"429":{"$ref":"#/components/responses/E429"}}}},"/v1/carrier_accounts/{id}/test":{"post":{"tags":["Carriers"],"summary":"Test a saved carrier account","description":"The same checks as testing unsaved credentials, run with the account's stored credentials, including the implicit `ca_env_fedex` account. The result is kept as the account's `last_test`. A `warn` on `labels` flags the account's rates `purchasable: false` and keeps automatic picks from choosing them.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectionTest"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}}}},"/v1/carrier_accounts/{id}":{"get":{"tags":["Carriers"],"summary":"Get a carrier account","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CarrierAccount"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}},"patch":{"tags":["Carriers"],"summary":"Update a carrier account","description":"Disabling an account stops it quoting and buying; labels and trackers it already made can still be voided and tracked. `credentials` replaces the stored ones as a whole; changing credentials or settings clears `last_test`. The implicit `ca_env_fedex` account can't be changed.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCarrierAccount"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CarrierAccount"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"422":{"$ref":"#/components/responses/E422"}}},"delete":{"tags":["Carriers"],"summary":"Delete a carrier account","description":"Only accounts nothing was bought or tracked with; disable the others instead.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"}}}},"/v1/addresses":{"post":{"tags":["Addresses"],"summary":"Create an address","description":"Set `verify` to correct the address with FedEx, or `verify_strict` to reject one FedEx can't resolve.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAddress"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Address"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/addresses/{id}":{"get":{"tags":["Addresses"],"summary":"Get an address","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Address"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/rates":{"post":{"tags":["Rates"],"summary":"Quote rates","description":"Prices for a package without creating a shipment, e.g. at checkout. Every enabled carrier account is quoted in parallel; with more than one, each gets a time budget (default 1.5 s), and carriers that are late, fail or can't price the request are listed in `carrier_errors` instead of failing the quote. Narrow it with `carrier` or `carrier_account_id`. Pass `protection` to get the protection fee too. `?descriptive` adds a plain-English guide to each service.","parameters":[{"name":"descriptive","in":"query","required":false,"schema":{"type":"string","enum":["0","1","","true","false"]}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteRates"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateQuote"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"},"502":{"$ref":"#/components/responses/E502"},"503":{"$ref":"#/components/responses/E503"}}}},"/v1/rates/compare":{"post":{"tags":["Rates"],"summary":"Preview a batch","description":"Takes the same body as `POST /v1/batches` and returns what it would buy for each order, without buying: the chosen service and packaging, the best alternative (One Rate vs. your own packaging), and the difference, plus totals. `one_rate` defaults to `compare` here. Quotes are cached, so a batch sent soon after buys at these prices. One order failing doesn't fail the rest.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompareRates"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateComparison"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/shipments":{"post":{"tags":["Shipments"],"summary":"Create a shipment","description":"Creates a shipment and quotes rates from every enabled carrier account (see `POST /v1/rates`). Add `service` to buy the label in the same call, with `carrier` or `carrier_account_id` to pick between carriers offering the same service. If that purchase fails, the error includes `shipment_id`.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateShipment"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Shipment"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"409":{"$ref":"#/components/responses/E409"},"422":{"$ref":"#/components/responses/E422"},"429":{"$ref":"#/components/responses/E429"},"502":{"$ref":"#/components/responses/E502"},"503":{"$ref":"#/components/responses/E503"}}},"get":{"tags":["Shipments"],"summary":"List shipments","description":"Newest first.","parameters":[{"name":"page_size","in":"query","required":false,"schema":{"default":20,"type":"integer","minimum":1,"maximum":100}},{"name":"before_id","in":"query","required":false,"schema":{"type":"string","maxLength":64}},{"name":"reference","in":"query","required":false,"schema":{"type":"string","maxLength":255}},{"name":"q","in":"query","required":false,"schema":{"description":"Search the recipient's name or company, the tracking number (prefix) or the reference","type":"string","minLength":1,"maxLength":100}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["created","purchasing","purchase_unknown","purchased","refunded"]}},{"name":"service","in":"query","required":false,"schema":{"description":"The selected rate's service code, e.g. `FEDEX_GROUND`","type":"string","minLength":1,"maxLength":64}},{"name":"from","in":"query","required":false,"schema":{"description":"Bought (or, without a label, created) at or after this. An ISO timestamp or a `YYYY-MM-DD` date","type":"string","maxLength":40}},{"name":"to","in":"query","required":false,"schema":{"description":"Bought (or, without a label, created) before this","type":"string","maxLength":40}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShipmentList"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}}},"/v1/shipments/{id}":{"get":{"tags":["Shipments"],"summary":"Get a shipment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Shipment"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/shipments/{id}/rerate":{"post":{"tags":["Shipments"],"summary":"Re-rate","description":"Fresh rates for an unpurchased shipment.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Shipment"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"502":{"$ref":"#/components/responses/E502"}}}},"/v1/shipments/{id}/buy":{"post":{"tags":["Shipments"],"summary":"Buy a label","description":"Pass exactly one of `rate_id` or `service`. With `service`, add `carrier` or `carrier_account_id` to choose between carriers offering it; otherwise the cheapest matching rate is bought. The label comes from the account that quoted the rate. Fails with `CARRIER.UNSUPPORTED_OPTION` when that carrier can't print the `label_format`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuyShipment"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Shipment"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"422":{"$ref":"#/components/responses/E422"},"429":{"$ref":"#/components/responses/E429"},"502":{"$ref":"#/components/responses/E502"},"503":{"$ref":"#/components/responses/E503"}}}},"/v1/shipments/{id}/return":{"post":{"tags":["Shipments"],"summary":"Buy a return label","description":"Creates a return shipment for a purchased shipment (addresses swapped, same parcel) and buys it straight away. `service` and `options` default to the original's; Ground and Home Delivery are interchangeable. The two shipments link through `return_shipment_id` and `return_of`. If the purchase fails, the error includes `shipment_id`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReturn"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Shipment"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"422":{"$ref":"#/components/responses/E422"},"429":{"$ref":"#/components/responses/E429"},"502":{"$ref":"#/components/responses/E502"},"503":{"$ref":"#/components/responses/E503"}}}},"/v1/shipments/{id}/reconcile":{"post":{"tags":["Shipments"],"summary":"Reconcile a purchase","description":"Asks FedEx whether a `purchase_unknown` label was created, then restores or voids it. The cron also does this.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Shipment"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"}}}},"/v1/shipments/{id}/refund":{"post":{"tags":["Shipments"],"summary":"Void a label","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Shipment"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/shipments/{id}/label":{"get":{"tags":["Shipments"],"summary":"Download the label","description":"A 4×6 PDF, PNG or ZPL file, depending on the shipment's `label_format`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The label file","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}},"application/x-zpl":{"schema":{"type":"string"}},"image/png":{"schema":{"type":"string","format":"binary"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/shipments/{id}/forms/{form_type}":{"get":{"tags":["Shipments"],"summary":"Download a customs form","description":"A customs document listed in the shipment's `forms`, such as `commercial_invoice`, usually a letter-size PDF. Print it and attach it to the parcel unless `submitted_electronically` is `true`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"form_type","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The form file","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}},"image/png":{"schema":{"type":"string","format":"binary"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/batches":{"post":{"tags":["Batches"],"summary":"Buy labels in bulk","description":"Up to 100 orders, bought in the background. Returns straight away; poll the batch or listen for `batch.completed`, then print every label from `labels_url`. `service` can be a FedEx code, `cheapest` or `fastest`; `FEDEX_GROUND` and `GROUND_HOME_DELIVERY` are interchangeable. With `one_rate: \"compare\"`, each order is quoted in its own box and in the smallest FedEx box it fits with One Rate, and the better one is bought; each item's `packaging` says which box to pack it in.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBatch"}}}},"responses":{"202":{"description":"Accepted; labels are being bought","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Batch"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"},"429":{"$ref":"#/components/responses/E429"}}},"get":{"tags":["Batches"],"summary":"List batches","description":"Newest first, without items; get a batch for those.","parameters":[{"name":"page_size","in":"query","required":false,"schema":{"default":20,"type":"integer","minimum":1,"maximum":100}},{"name":"before_id","in":"query","required":false,"schema":{"type":"string","maxLength":64}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchList"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}}},"/v1/batches/{id}":{"get":{"tags":["Batches"],"summary":"Get a batch","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Batch"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/batches/{id}/labels":{"get":{"tags":["Batches"],"summary":"Print every label","description":"One file with every purchased label, in order: a PDF with one 4×6 page per label, or ZPL labels back to back. Print at 100% on 4×6 paper. Returns 409 while the batch is processing unless `partial` is set.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"partial","in":"query","required":false,"schema":{"type":"string","enum":["0","1","","true","false"]}}],"responses":{"200":{"description":"All labels in one file","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}},"application/x-zpl":{"schema":{"type":"string"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"}}}},"/v1/labels/merge":{"post":{"tags":["Shipments"],"summary":"Print labels together","description":"Up to 100 purchased shipments' PDF labels as one 4×6 PDF, in the order given. Fails with 422 and the offending IDs if any shipment isn't purchased or its label isn't a PDF.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MergeLabels"}}}},"responses":{"200":{"description":"The merged labels","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/reports/summary":{"get":{"tags":["Reports"],"summary":"Spend and exceptions","description":"Labels bought and spend for `from` (inclusive) to `to` (exclusive, default now), by service and by day, plus One Rate savings from batch orders, protection fees against claims paid, and what needs action. Pass `utc_offset` (minutes east of UTC) to split days in your timezone.","parameters":[{"name":"from","in":"query","required":false,"schema":{"type":"string","maxLength":40}},{"name":"to","in":"query","required":false,"schema":{"type":"string","maxLength":40}},{"name":"utc_offset","in":"query","required":false,"schema":{"default":0,"type":"integer","minimum":-720,"maximum":840}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportSummary"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/drafts":{"get":{"tags":["Drafts"],"summary":"List drafts","description":"Most recently saved first, at most 100.","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DraftList"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}},"post":{"tags":["Drafts"],"summary":"Create a draft","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveDraft"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Draft"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/drafts/{id}":{"get":{"tags":["Drafts"],"summary":"Get a draft","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Draft"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}},"put":{"tags":["Drafts"],"summary":"Save a draft","description":"Creates the draft with the ID you choose (8–64 letters, digits, `-` or `_`), or replaces its payload. Saving the 101st draft deletes the least recently saved.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveDraft"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Draft"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"}}},"delete":{"tags":["Drafts"],"summary":"Delete a draft","description":"Succeeds whether or not the draft exists.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}}},"/v1/shipments/{id}/claims":{"post":{"tags":["Package protection"],"summary":"Open a claim","description":"The shipment must be purchased and protected, with no other open claim.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateClaim"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Claim"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/claims":{"get":{"tags":["Package protection"],"summary":"List claims","description":"Newest first.","parameters":[{"name":"page_size","in":"query","required":false,"schema":{"default":20,"type":"integer","minimum":1,"maximum":100}},{"name":"before_id","in":"query","required":false,"schema":{"type":"string","maxLength":64}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["open","approved","denied"]}},{"name":"shipment_id","in":"query","required":false,"schema":{"type":"string","maxLength":64}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimList"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}}},"/v1/claims/{id}":{"get":{"tags":["Package protection"],"summary":"Get a claim","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Claim"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}},"patch":{"tags":["Package protection"],"summary":"Decide a claim","description":"Approve (with a `resolution`) or deny an open claim, or update notes on any claim.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateClaim"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Claim"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"409":{"$ref":"#/components/responses/E409"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/claims/{id}/photos/{photo_id}":{"get":{"tags":["Package protection"],"summary":"Get a claim photo","description":"The image a customer attached to their claim, as uploaded.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"photo_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The photo","content":{"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/png":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/heic":{"schema":{"type":"string","format":"binary"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/protection/summary":{"get":{"tags":["Package protection"],"summary":"Fees vs. claims","description":"Fees from purchased, protected shipments compared with what approved claims cost.","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProtectionSummary"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}}},"/v1/trackers":{"post":{"tags":["Tracking"],"summary":"Track a package","description":"Any tracking number, including ones not bought here. The carrier is detected from the number's format (FedEx, UPS and USPS patterns); set `carrier` to override. Numbers that match nothing are tracked with FedEx. Fails with `CARRIER.NOT_CONFIGURED` when no enabled account exists for the carrier.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTracker"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Tracker"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"},"502":{"$ref":"#/components/responses/E502"}}},"get":{"tags":["Tracking"],"summary":"List trackers","description":"Newest first, including the trackers made for labels bought here. Filter by `status`, `carrier` or the start of `tracking_code`.","parameters":[{"name":"page_size","in":"query","required":false,"schema":{"default":20,"type":"integer","minimum":1,"maximum":100}},{"name":"before_id","in":"query","required":false,"schema":{"type":"string","maxLength":64}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["unknown","pre_transit","in_transit","out_for_delivery","delivered","available_for_pickup","return_to_sender","failure"]}},{"name":"carrier","in":"query","required":false,"schema":{"description":"A carrier ID or display name, e.g. `fedex` or `FedEx`","type":"string","minLength":1,"maxLength":64}},{"name":"tracking_code","in":"query","required":false,"schema":{"description":"Tracking numbers that start with this","type":"string","minLength":1,"maxLength":64}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrackerList"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}}},"/v1/trackers/{id}":{"get":{"tags":["Tracking"],"summary":"Get a tracker","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Tracker"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/trackers/{id}/refresh":{"post":{"tags":["Tracking"],"summary":"Refresh now","description":"Trackers refresh on their own about every 15 minutes.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Tracker"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"502":{"$ref":"#/components/responses/E502"}}}},"/v1/webhooks":{"post":{"tags":["Webhooks"],"summary":"Add a webhook","description":"HTTPS only. The response is the only time `secret` is shown.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhook"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"}}},"get":{"tags":["Webhooks"],"summary":"List webhooks","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}}},"required":["webhooks"]}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}}},"/v1/webhooks/{id}":{"get":{"tags":["Webhooks"],"summary":"Get a webhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}},"patch":{"tags":["Webhooks"],"summary":"Update a webhook","description":"Change the URL, or pause and resume it with `disabled`. A disabled webhook gets no new events, and deliveries already queued for it fail instead of being sent; redeliver them after resuming.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWebhook"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"422":{"$ref":"#/components/responses/E422"}}},"delete":{"tags":["Webhooks"],"summary":"Delete a webhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/webhooks/{id}/rotate_secret":{"post":{"tags":["Webhooks"],"summary":"Rotate the signing secret","description":"The old secret stops working immediately, including for deliveries already queued. The response is the only time the new `secret` is shown.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/webhooks/{id}/test":{"post":{"tags":["Webhooks"],"summary":"Send a test event","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"202":{"description":"Queued","content":{"application/json":{"schema":{"type":"object","properties":{"event_id":{"type":"string"}},"required":["event_id"]}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/webhooks/{id}/deliveries":{"get":{"tags":["Webhooks"],"summary":"Delivery history","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"page_size","in":"query","required":false,"schema":{"default":20,"type":"integer","minimum":1,"maximum":100}},{"name":"before_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["pending","retrying","succeeded","failed"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"deliveries":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}},"has_more":{"type":"boolean"}},"required":["deliveries","has_more"]}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}}},"/v1/webhook_deliveries/{id}":{"get":{"tags":["Webhooks"],"summary":"Get a delivery","description":"With the `event` it carries, exactly as it was sent. Response bodies aren't kept; `response_status` and `last_error` say how the endpoint answered.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDelivery"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/webhook_deliveries/{id}/redeliver":{"post":{"tags":["Webhooks"],"summary":"Redeliver","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"202":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDelivery"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/api_keys":{"post":{"tags":["Account"],"summary":"Create an API key","description":"Needs `keys:manage` (owners and admins, or the root key). The key belongs to the caller's organization and records who made it. Choose `scopes`, daily limits and an expiry to limit what a leaked key can do. The response is the only time `key` is shown.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKey"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"}}},"get":{"tags":["Account"],"summary":"List API keys","description":"Needs `keys:manage`. Only the organization's own keys.","parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"api_keys":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}},"required":["api_keys"]}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}}},"/v1/audit_events":{"get":{"tags":["Account"],"summary":"Audit log","description":"Needs `audit:read` (owners and admins). The organization's events: who bought or voided labels, decided claims, changed settings or protection pricing, and created or revoked keys and webhooks. Newest first. Events are kept indefinitely.","parameters":[{"name":"page_size","in":"query","required":false,"schema":{"default":20,"type":"integer","minimum":1,"maximum":100}},{"name":"before_id","in":"query","required":false,"schema":{"type":"string","maxLength":64}},{"name":"action","in":"query","required":false,"schema":{"type":"string","maxLength":64}},{"name":"actor","in":"query","required":false,"schema":{"type":"string","maxLength":64}},{"name":"exclude_actions","in":"query","required":false,"schema":{"description":"Comma-separated actions to leave out, e.g. `auth.signed_in,auth.signed_out`","type":"string","maxLength":1000}},{"name":"from","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"audit_events":{"type":"array","items":{"$ref":"#/components/schemas/AuditEvent"}},"has_more":{"type":"boolean"}},"required":["audit_events","has_more"]}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/request_logs":{"get":{"tags":["Account"],"summary":"List API requests","description":"Needs `logs:read` (owners and admins). Every authenticated `/v1` request made in this mode, newest first, without bodies; fetch one for them. Kept for `REQUEST_LOG_RETENTION_DAYS` (30 by default). Reading the log and `GET /v1/me` aren't logged.","parameters":[{"name":"page_size","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":100}},{"name":"before_id","in":"query","required":false,"schema":{"type":"string","maxLength":64}},{"name":"status","in":"query","required":false,"schema":{"type":"string","pattern":"^([1-5]xx|[1-5]\\d\\d)$"}},{"name":"method","in":"query","required":false,"schema":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"]}},{"name":"path_prefix","in":"query","required":false,"schema":{"description":"e.g. /v1/shipments","type":"string","minLength":1,"maxLength":200}},{"name":"api_key","in":"query","required":false,"schema":{"description":"An API key ID, `root`, `user_…`, or a member's email","type":"string","maxLength":254}},{"name":"error_code","in":"query","required":false,"schema":{"type":"string","maxLength":100}},{"name":"object_id","in":"query","required":false,"schema":{"description":"A shipment, batch, claim or tracker ID: the calls that named or returned it","type":"string","maxLength":64}},{"name":"source","in":"query","required":false,"schema":{"description":"`api` for calls made with an API key or the root key, `dashboard` for calls a signed-in member made from the admin. Both when left out","type":"string","enum":["api","dashboard"]}},{"name":"from","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"request_logs":{"type":"array","items":{"$ref":"#/components/schemas/RequestLog"}},"has_more":{"type":"boolean"}},"required":["request_logs","has_more"]}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"422":{"$ref":"#/components/responses/E422"}}}},"/v1/request_logs/{id}":{"get":{"tags":["Account"],"summary":"Get an API request","description":"Needs `logs:read`. The request and response bodies are redacted (credentials, secrets, tokens, carrier account numbers; phone numbers and emails are masked) and cut at 16 KB each.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestLogDetail"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/v1/waitlist":{"get":{"tags":["Account"],"summary":"List waitlist signups","description":"Root key, or an owner of the first organization. Signups from the landing page form, newest first. Always the live list, whatever the key's mode.","parameters":[{"name":"page_size","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":100}},{"name":"before_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"q","in":"query","required":false,"schema":{"description":"Only signups whose email contains this text","type":"string","maxLength":254}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/WaitlistEntry"}},"has_more":{"type":"boolean"},"total_count":{"type":"integer","description":"How many signups match, across all pages"}},"required":["entries","has_more","total_count"]}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}}},"/v1/waitlist/export":{"get":{"tags":["Account"],"summary":"Export the waitlist as CSV","description":"Root key, or an owner of the first organization. Columns: `email`, `store_url`, `joined_at`.","parameters":[],"responses":{"200":{"description":"CSV file","content":{"text/csv":{"schema":{"type":"string"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"}}}},"/v1/api_keys/{id}":{"patch":{"tags":["Account"],"summary":"Update an API key","description":"Needs `keys:manage`. Change a working key's `name`, `scopes`, daily limits or expiry; `null` removes a limit or the expiry. The mode can't change, and revoked keys can't be edited. Other servers can take up to 30 seconds to see new scopes or expiry.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateApiKey"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"},"422":{"$ref":"#/components/responses/E422"}}},"delete":{"tags":["Account"],"summary":"Revoke an API key","description":"Needs `keys:manage`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Revoked"},"401":{"$ref":"#/components/responses/E401"},"403":{"$ref":"#/components/responses/E403"},"404":{"$ref":"#/components/responses/E404"}}}},"/t/{token}/status.json":{"get":{"tags":["Public tracking"],"summary":"Tracking page data","description":"What the recipient's tracking page shows, for stores that render their own. The token is the last segment of a shipment's `public_tracking_url`. No API key. Includes the destination city and state only, never the street address, phone or email. Unknown tokens return 404, and repeated misses from one IP are rate limited.","security":[],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTracking"}}}},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}}}},"/t/{token}/og.png":{"get":{"tags":["Public tracking"],"summary":"Link preview image","description":"A 1200×630 PNG with the store name, headline and progress, used as the page's `og:image`. Never shows an address. No API key.","security":[],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The image","content":{"image/png":{"schema":{"type":"string","format":"binary"}}}},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}}}},"/t/{token}/delivery.ics":{"get":{"tags":["Public tracking"],"summary":"Calendar file for the delivery day","description":"An all-day event on the estimated delivery date. 404 once delivered, without an estimate, or when the package is going back. No API key.","security":[],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"iCalendar file","content":{"text/calendar":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/E404"},"429":{"$ref":"#/components/responses/E429"}}}},"/health":{"get":{"tags":["Health"],"summary":"Liveness","security":[],"parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"carrier_mode":{"type":"string"}},"required":["ok","carrier_mode"]}}}}}}},"/health/ready":{"get":{"tags":["Health"],"summary":"Readiness","description":"Checks the databases are reachable, without calling FedEx.","security":[],"parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]}}}}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"Your API key, e.g. `sk_live_…`"},"sessionCookie":{"type":"apiKey","in":"cookie","name":"veloship.session_token","description":"Set by signing in to the admin. HttpOnly, SameSite=Lax. State-changing requests must carry a same-origin `Origin` header."}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"description":"Any unique string up to 255 characters. Retries with the same key return the first response for 24 hours.","schema":{"type":"string","maxLength":255}}},"responses":{"E401":{"description":"Missing, wrong or revoked API key, or no valid session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"E402":{"description":"Billing is required: the free live labels are used and there is no paying subscription (`BILLING.REQUIRED`), or the past-due grace period is over (`BILLING.PAST_DUE`). The error carries `billing_url`. Test mode is never refused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"E403":{"description":"Only the root key can do this (`FORBIDDEN`), the key or role lacks the required scope (`FORBIDDEN.SCOPE`), or a cookie-authenticated write came from another site (`FORBIDDEN.ORIGIN`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"E404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"E409":{"description":"Conflicts with the resource's current state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"E410":{"description":"Gone: the print job's file is past retention (`PRINT.FILE_EXPIRED`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"E413":{"description":"The request body is too large (`PAYLOAD_TOO_LARGE`, `BRANDING.LOGO_TOO_LARGE`): 256 KB for most endpoints, 512 KB for a logo, a 20 MB file for print jobs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"E422":{"description":"Validation failed, the carrier rejected the request (`CARRIER.UNSUPPORTED_OPTION`, `CARRIER.NOT_CONFIGURED`), or a shipping rule stopped it (`RULES.BLOCKED`, `RULES.NO_RATE`, `RULES.SERVICE_EXCLUDED`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"E429":{"description":"Rate limited; honor `Retry-After`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"E502":{"description":"The carrier failed or didn't confirm (`CARRIER.ALL_FAILED` when every carrier failed to quote)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"E503":{"description":"The carrier is unavailable; retry after `Retry-After`, or describing rules in English isn't set up (`RULES.AI_UNAVAILABLE`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"AddressInput":{"$id":"#/components/schemas/AddressInput","type":"object","properties":{"name":{"anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"null"}]},"company":{"anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"null"}]},"street1":{"type":"string","minLength":1,"maxLength":100},"street2":{"anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"null"}]},"city":{"type":"string","minLength":1,"maxLength":100},"state":{"anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"null"}]},"zip":{"type":"string","minLength":1,"maxLength":20},"country":{"default":"US","type":"string","minLength":2,"maxLength":2},"phone":{"anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"null"}]},"email":{"anyOf":[{"type":"string","maxLength":254,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"residential":{"type":["boolean","null"]}},"required":["street1","city","zip"]},"CreateAddress":{"$id":"#/components/schemas/CreateAddress","type":"object","properties":{"name":{"anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"null"}]},"company":{"anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"null"}]},"street1":{"type":"string","minLength":1,"maxLength":100},"street2":{"anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"null"}]},"city":{"type":"string","minLength":1,"maxLength":100},"state":{"anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"null"}]},"zip":{"type":"string","minLength":1,"maxLength":20},"country":{"default":"US","type":"string","minLength":2,"maxLength":2},"phone":{"anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"null"}]},"email":{"anyOf":[{"type":"string","maxLength":254,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"residential":{"type":["boolean","null"]},"verify":{"default":false,"type":"boolean"},"verify_strict":{"default":false,"type":"boolean"}},"required":["street1","city","zip"]},"Parcel":{"$id":"#/components/schemas/Parcel","type":"object","properties":{"weight":{"type":"number","exclusiveMinimum":0,"maximum":2400,"description":"ounces (FedEx Express limit is 150 lb)"},"predefined_package":{"type":"string","enum":["YOUR_PACKAGING","FEDEX_ENVELOPE","FEDEX_PAK","FEDEX_EXTRA_SMALL_BOX","FEDEX_SMALL_BOX","FEDEX_MEDIUM_BOX","FEDEX_LARGE_BOX","FEDEX_EXTRA_LARGE_BOX","FEDEX_TUBE","USPS_FLAT_RATE_ENVELOPE","USPS_LEGAL_FLAT_RATE_ENVELOPE","USPS_PADDED_FLAT_RATE_ENVELOPE","USPS_SMALL_FLAT_RATE_BOX","USPS_MEDIUM_FLAT_RATE_BOX","USPS_LARGE_FLAT_RATE_BOX","UPS_LETTER","UPS_TUBE","UPS_PAK","UPS_EXPRESS_BOX","UPS_EXPRESS_BOX_SMALL","UPS_EXPRESS_BOX_MEDIUM","UPS_EXPRESS_BOX_LARGE","UPS_SIMPLE_XS","UPS_SIMPLE_S","UPS_SIMPLE_M","UPS_SIMPLE_L","UPS_SIMPLE_XL"]},"length":{"type":"number","exclusiveMinimum":0,"maximum":119},"width":{"type":"number","exclusiveMinimum":0,"maximum":119},"height":{"type":"number","exclusiveMinimum":0,"maximum":119}},"required":["weight"]},"ParcelPreset":{"$id":"#/components/schemas/ParcelPreset","type":"object","properties":{"weight":{"type":"number","exclusiveMinimum":0,"maximum":2400,"description":"ounces (FedEx Express limit is 150 lb)"},"predefined_package":{"type":"string","enum":["YOUR_PACKAGING","FEDEX_ENVELOPE","FEDEX_PAK","FEDEX_EXTRA_SMALL_BOX","FEDEX_SMALL_BOX","FEDEX_MEDIUM_BOX","FEDEX_LARGE_BOX","FEDEX_EXTRA_LARGE_BOX","FEDEX_TUBE","USPS_FLAT_RATE_ENVELOPE","USPS_LEGAL_FLAT_RATE_ENVELOPE","USPS_PADDED_FLAT_RATE_ENVELOPE","USPS_SMALL_FLAT_RATE_BOX","USPS_MEDIUM_FLAT_RATE_BOX","USPS_LARGE_FLAT_RATE_BOX","UPS_LETTER","UPS_TUBE","UPS_PAK","UPS_EXPRESS_BOX","UPS_EXPRESS_BOX_SMALL","UPS_EXPRESS_BOX_MEDIUM","UPS_EXPRESS_BOX_LARGE","UPS_SIMPLE_XS","UPS_SIMPLE_S","UPS_SIMPLE_M","UPS_SIMPLE_L","UPS_SIMPLE_XL"]},"length":{"type":"number","exclusiveMinimum":0,"maximum":119},"width":{"type":"number","exclusiveMinimum":0,"maximum":119},"height":{"type":"number","exclusiveMinimum":0,"maximum":119}}},"ShipmentOptions":{"$id":"#/components/schemas/ShipmentOptions","type":"object","properties":{"one_rate":{"type":"boolean"},"signature":{"description":"Signature required on delivery. `none` is the default","type":"string","enum":["none","indirect","direct","adult"]},"declared_value":{"description":"What the package is worth, e.g. \"250.00\". FedEx liability is $100 without it","type":"string","pattern":"^\\d{1,7}(\\.\\d{1,2})?$"},"saturday_delivery":{"type":"boolean"},"duties_payer":{"description":"Who pays import duties and taxes on an international shipment: `recipient` (the default, DAP) or `sender` (DDP). Ignored within a country","type":"string","enum":["sender","recipient"]}},"additionalProperties":false},"CustomsInfoInput":{"$id":"#/components/schemas/CustomsInfoInput","type":"object","properties":{"contents_type":{"default":"merchandise","type":"string","enum":["merchandise","gift","documents","returned_goods","sample","other"]},"contents_explanation":{"description":"Required when `contents_type` is `other`","anyOf":[{"type":"string","minLength":1,"maxLength":255},{"type":"null"}]},"customs_certify":{"default":false,"description":"You certify the declaration is correct. Requires `customs_signer`","type":"boolean"},"customs_signer":{"description":"The person certifying the declaration","anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"null"}]},"eel_pfc":{"description":"Export statement: an FTR exemption such as `NOEEI 30.37(a)`, or `AES X20261015123456` when EEI was filed. Defaults to `NOEEI 30.37(a)` (`NOEEI 30.36` to Canada). Must be an AES ITN when one Schedule B number is worth more than $2,500 and the destination isn't Canada","anyOf":[{"type":"string","minLength":1,"maxLength":64},{"type":"null"}]},"restriction_type":{"default":"none","type":"string","enum":["none","other","quarantine","sanitary_phytosanitary_inspection"]},"restriction_comments":{"description":"Required unless `restriction_type` is `none`","anyOf":[{"type":"string","minLength":1,"maxLength":255},{"type":"null"}]},"non_delivery_option":{"default":"return","description":"What the destination does with a parcel it can't deliver","type":"string","enum":["return","abandon"]},"customs_items":{"minItems":1,"maxItems":100,"type":"array","items":{"$ref":"#/components/schemas/CustomsItemInput"}}},"required":["customs_items"]},"CustomsItemInput":{"$id":"#/components/schemas/CustomsItemInput","type":"object","properties":{"description":{"type":"string","minLength":1,"maxLength":255,"description":"What the item is, in words a customs officer understands, e.g. `Cotton T-shirt`"},"quantity":{"type":"integer","exclusiveMinimum":0,"maximum":100000},"value":{"description":"The whole line's value in USD, e.g. \"40.00\" for two $20 shirts","type":["string","number"]},"weight":{"type":"number","exclusiveMinimum":0,"maximum":2400,"description":"The whole line's weight in ounces"},"origin_country":{"description":"Where the goods were made","type":"string","pattern":"^[A-Za-z]{2}$"},"hs_tariff_number":{"description":"HS or Schedule B code, 6 to 10 digits, dots allowed. Returned without the dots","anyOf":[{"type":"string","pattern":"^\\d[\\d.]*$"},{"type":"null"}]},"code":{"description":"Your SKU","anyOf":[{"type":"string","minLength":1,"maxLength":64},{"type":"null"}]}},"required":["description","quantity","value","weight"]},"CreateReturn":{"$id":"#/components/schemas/CreateReturn","type":"object","properties":{"service":{"description":"Defaults to the service the original shipment used","type":"string","maxLength":64},"label_format":{"default":"PDF","type":"string","enum":["PDF","PNG","ZPLII"]},"options":{"description":"Defaults to the original shipment's options","$ref":"#/components/schemas/ShipmentOptions"}}},"QuoteRates":{"$id":"#/components/schemas/QuoteRates","type":"object","properties":{"carrier":{"description":"Only use this carrier (ID or display name, e.g. `fedex`)","type":"string","minLength":1,"maxLength":64},"carrier_account_id":{"description":"Only use this carrier account","type":"string","maxLength":64,"format":"starts_with","pattern":"^ca_.*"},"from_address":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"starts_with","pattern":"^adr_.*"}},"required":["id"],"additionalProperties":false},{"$ref":"#/components/schemas/AddressInput"}]},"to_address":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"starts_with","pattern":"^adr_.*"}},"required":["id"],"additionalProperties":false},{"$ref":"#/components/schemas/AddressInput"}]},"parcel":{"anyOf":[{"type":"object","properties":{"weight":{"type":"number","exclusiveMinimum":0,"maximum":2400,"description":"ounces (FedEx Express limit is 150 lb)"},"predefined_package":{"type":"string","enum":["YOUR_PACKAGING","FEDEX_ENVELOPE","FEDEX_PAK","FEDEX_EXTRA_SMALL_BOX","FEDEX_SMALL_BOX","FEDEX_MEDIUM_BOX","FEDEX_LARGE_BOX","FEDEX_EXTRA_LARGE_BOX","FEDEX_TUBE","USPS_FLAT_RATE_ENVELOPE","USPS_LEGAL_FLAT_RATE_ENVELOPE","USPS_PADDED_FLAT_RATE_ENVELOPE","USPS_SMALL_FLAT_RATE_BOX","USPS_MEDIUM_FLAT_RATE_BOX","USPS_LARGE_FLAT_RATE_BOX","UPS_LETTER","UPS_TUBE","UPS_PAK","UPS_EXPRESS_BOX","UPS_EXPRESS_BOX_SMALL","UPS_EXPRESS_BOX_MEDIUM","UPS_EXPRESS_BOX_LARGE","UPS_SIMPLE_XS","UPS_SIMPLE_S","UPS_SIMPLE_M","UPS_SIMPLE_L","UPS_SIMPLE_XL"]},"length":{"type":"number","exclusiveMinimum":0,"maximum":119},"width":{"type":"number","exclusiveMinimum":0,"maximum":119},"height":{"type":"number","exclusiveMinimum":0,"maximum":119},"preset":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,39}$"}},"required":["preset"],"additionalProperties":false},{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,39}$"},{"$ref":"#/components/schemas/Parcel"}]},"options":{"$ref":"#/components/schemas/ShipmentOptions"},"protection":{"type":"object","properties":{"value":{"type":"string","pattern":"^\\d{1,7}(\\.\\d{1,2})?$"}},"required":["value"],"additionalProperties":false},"order":{"type":"object","properties":{"value":{"description":"What the order is worth, e.g. \"149.00\" (a number works too). Defaults to the sum of the items' `value` × `quantity`","type":["string","number"]},"currency":{"description":"Three-letter currency of `value`. Informational: nothing is converted","type":"string","minLength":3,"maxLength":3},"tags":{"description":"e.g. `[\"fragile\", \"gift\"]`; shipping rules can test for them","maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":64}},"shipping_method":{"description":"What the customer chose at checkout, e.g. `Expedited`","type":"string","minLength":1,"maxLength":100},"shipping_paid":{"description":"What the customer paid for shipping at checkout, e.g. \"12.95\", in `currency`. `max_price` can cap the label at it","type":["string","number"]},"items":{"maxItems":500,"type":"array","items":{"type":"object","properties":{"sku":{"type":"string","minLength":1,"maxLength":100},"quantity":{"default":1,"type":"integer","minimum":1,"maximum":100000},"value":{"description":"The price of one unit","type":["string","number"]}},"required":["sku"],"additionalProperties":false}}},"additionalProperties":false,"description":"What's being ordered. Shipping rules can look at it; nothing here is sent to the carrier. Shopify's `total_price`, `tags`, shipping line and line items map onto it"},"apply_rules":{"description":"`false` skips shipping rules for this request. Defaults to true","type":"boolean"},"customs_info":{"description":"The customs declaration, with EasyPost's field names. Required when the parcel crosses a customs border: the origin and destination countries differ, other than between the US and its territories","$ref":"#/components/schemas/CustomsInfoInput"},"sort":{"default":"best_value","type":"string","enum":["best_value","cheapest","fastest"]}},"required":["to_address","parcel"]},"CreateShipment":{"$id":"#/components/schemas/CreateShipment","type":"object","properties":{"carrier":{"description":"Only use this carrier (ID or display name, e.g. `fedex`)","type":"string","minLength":1,"maxLength":64},"carrier_account_id":{"description":"Only use this carrier account","type":"string","maxLength":64,"format":"starts_with","pattern":"^ca_.*"},"from_address":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"starts_with","pattern":"^adr_.*"}},"required":["id"],"additionalProperties":false},{"$ref":"#/components/schemas/AddressInput"}]},"to_address":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"starts_with","pattern":"^adr_.*"}},"required":["id"],"additionalProperties":false},{"$ref":"#/components/schemas/AddressInput"}]},"parcel":{"anyOf":[{"type":"object","properties":{"weight":{"type":"number","exclusiveMinimum":0,"maximum":2400,"description":"ounces (FedEx Express limit is 150 lb)"},"predefined_package":{"type":"string","enum":["YOUR_PACKAGING","FEDEX_ENVELOPE","FEDEX_PAK","FEDEX_EXTRA_SMALL_BOX","FEDEX_SMALL_BOX","FEDEX_MEDIUM_BOX","FEDEX_LARGE_BOX","FEDEX_EXTRA_LARGE_BOX","FEDEX_TUBE","USPS_FLAT_RATE_ENVELOPE","USPS_LEGAL_FLAT_RATE_ENVELOPE","USPS_PADDED_FLAT_RATE_ENVELOPE","USPS_SMALL_FLAT_RATE_BOX","USPS_MEDIUM_FLAT_RATE_BOX","USPS_LARGE_FLAT_RATE_BOX","UPS_LETTER","UPS_TUBE","UPS_PAK","UPS_EXPRESS_BOX","UPS_EXPRESS_BOX_SMALL","UPS_EXPRESS_BOX_MEDIUM","UPS_EXPRESS_BOX_LARGE","UPS_SIMPLE_XS","UPS_SIMPLE_S","UPS_SIMPLE_M","UPS_SIMPLE_L","UPS_SIMPLE_XL"]},"length":{"type":"number","exclusiveMinimum":0,"maximum":119},"width":{"type":"number","exclusiveMinimum":0,"maximum":119},"height":{"type":"number","exclusiveMinimum":0,"maximum":119},"preset":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,39}$"}},"required":["preset"],"additionalProperties":false},{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,39}$"},{"$ref":"#/components/schemas/Parcel"}]},"options":{"$ref":"#/components/schemas/ShipmentOptions"},"protection":{"type":"object","properties":{"value":{"type":"string","pattern":"^\\d{1,7}(\\.\\d{1,2})?$"}},"required":["value"],"additionalProperties":false},"order":{"type":"object","properties":{"value":{"description":"What the order is worth, e.g. \"149.00\" (a number works too). Defaults to the sum of the items' `value` × `quantity`","type":["string","number"]},"currency":{"description":"Three-letter currency of `value`. Informational: nothing is converted","type":"string","minLength":3,"maxLength":3},"tags":{"description":"e.g. `[\"fragile\", \"gift\"]`; shipping rules can test for them","maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":64}},"shipping_method":{"description":"What the customer chose at checkout, e.g. `Expedited`","type":"string","minLength":1,"maxLength":100},"shipping_paid":{"description":"What the customer paid for shipping at checkout, e.g. \"12.95\", in `currency`. `max_price` can cap the label at it","type":["string","number"]},"items":{"maxItems":500,"type":"array","items":{"type":"object","properties":{"sku":{"type":"string","minLength":1,"maxLength":100},"quantity":{"default":1,"type":"integer","minimum":1,"maximum":100000},"value":{"description":"The price of one unit","type":["string","number"]}},"required":["sku"],"additionalProperties":false}}},"additionalProperties":false,"description":"What's being ordered. Shipping rules can look at it; nothing here is sent to the carrier. Shopify's `total_price`, `tags`, shipping line and line items map onto it"},"apply_rules":{"description":"`false` skips shipping rules for this request. Defaults to true","type":"boolean"},"customs_info":{"description":"The customs declaration, with EasyPost's field names. Required when the parcel crosses a customs border: the origin and destination countries differ, other than between the US and its territories","$ref":"#/components/schemas/CustomsInfoInput"},"reference":{"type":"string","minLength":1,"maxLength":255},"service":{"type":"string","maxLength":64},"label_format":{"type":"string","enum":["PDF","PNG","ZPLII"]}},"required":["to_address","parcel"]},"BuyShipment":{"$id":"#/components/schemas/BuyShipment","type":"object","properties":{"rate_id":{"type":"string","maxLength":64},"service":{"type":"string","maxLength":64},"carrier":{"description":"Only use this carrier (ID or display name, e.g. `fedex`)","type":"string","minLength":1,"maxLength":64},"carrier_account_id":{"description":"Only use this carrier account","type":"string","maxLength":64,"format":"starts_with","pattern":"^ca_.*"},"label_format":{"default":"PDF","type":"string","enum":["PDF","PNG","ZPLII"]}}},"CreateBatch":{"$id":"#/components/schemas/CreateBatch","type":"object","properties":{"shipments":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"object","properties":{"carrier":{"description":"Only use this carrier (ID or display name, e.g. `fedex`)","type":"string","minLength":1,"maxLength":64},"carrier_account_id":{"description":"Only use this carrier account","type":"string","maxLength":64,"format":"starts_with","pattern":"^ca_.*"},"from_address":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"starts_with","pattern":"^adr_.*"}},"required":["id"],"additionalProperties":false},{"$ref":"#/components/schemas/AddressInput"}]},"to_address":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"starts_with","pattern":"^adr_.*"}},"required":["id"],"additionalProperties":false},{"$ref":"#/components/schemas/AddressInput"}]},"parcel":{"anyOf":[{"type":"object","properties":{"weight":{"type":"number","exclusiveMinimum":0,"maximum":2400,"description":"ounces (FedEx Express limit is 150 lb)"},"predefined_package":{"type":"string","enum":["YOUR_PACKAGING","FEDEX_ENVELOPE","FEDEX_PAK","FEDEX_EXTRA_SMALL_BOX","FEDEX_SMALL_BOX","FEDEX_MEDIUM_BOX","FEDEX_LARGE_BOX","FEDEX_EXTRA_LARGE_BOX","FEDEX_TUBE","USPS_FLAT_RATE_ENVELOPE","USPS_LEGAL_FLAT_RATE_ENVELOPE","USPS_PADDED_FLAT_RATE_ENVELOPE","USPS_SMALL_FLAT_RATE_BOX","USPS_MEDIUM_FLAT_RATE_BOX","USPS_LARGE_FLAT_RATE_BOX","UPS_LETTER","UPS_TUBE","UPS_PAK","UPS_EXPRESS_BOX","UPS_EXPRESS_BOX_SMALL","UPS_EXPRESS_BOX_MEDIUM","UPS_EXPRESS_BOX_LARGE","UPS_SIMPLE_XS","UPS_SIMPLE_S","UPS_SIMPLE_M","UPS_SIMPLE_L","UPS_SIMPLE_XL"]},"length":{"type":"number","exclusiveMinimum":0,"maximum":119},"width":{"type":"number","exclusiveMinimum":0,"maximum":119},"height":{"type":"number","exclusiveMinimum":0,"maximum":119},"preset":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,39}$"}},"required":["preset"],"additionalProperties":false},{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,39}$"},{"$ref":"#/components/schemas/Parcel"}]},"options":{"$ref":"#/components/schemas/ShipmentOptions"},"protection":{"type":"object","properties":{"value":{"type":"string","pattern":"^\\d{1,7}(\\.\\d{1,2})?$"}},"required":["value"],"additionalProperties":false},"order":{"type":"object","properties":{"value":{"description":"What the order is worth, e.g. \"149.00\" (a number works too). Defaults to the sum of the items' `value` × `quantity`","type":["string","number"]},"currency":{"description":"Three-letter currency of `value`. Informational: nothing is converted","type":"string","minLength":3,"maxLength":3},"tags":{"description":"e.g. `[\"fragile\", \"gift\"]`; shipping rules can test for them","maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":64}},"shipping_method":{"description":"What the customer chose at checkout, e.g. `Expedited`","type":"string","minLength":1,"maxLength":100},"shipping_paid":{"description":"What the customer paid for shipping at checkout, e.g. \"12.95\", in `currency`. `max_price` can cap the label at it","type":["string","number"]},"items":{"maxItems":500,"type":"array","items":{"type":"object","properties":{"sku":{"type":"string","minLength":1,"maxLength":100},"quantity":{"default":1,"type":"integer","minimum":1,"maximum":100000},"value":{"description":"The price of one unit","type":["string","number"]}},"required":["sku"],"additionalProperties":false}}},"additionalProperties":false,"description":"What's being ordered. Shipping rules can look at it; nothing here is sent to the carrier. Shopify's `total_price`, `tags`, shipping line and line items map onto it"},"apply_rules":{"description":"`false` skips shipping rules for this request. Defaults to true","type":"boolean"},"customs_info":{"description":"The customs declaration, with EasyPost's field names. Required when the parcel crosses a customs border: the origin and destination countries differ, other than between the US and its territories","$ref":"#/components/schemas/CustomsInfoInput"},"reference":{"type":"string","minLength":1,"maxLength":255},"service":{"type":"string","minLength":1,"maxLength":64},"one_rate":{"type":"string","enum":["compare","as_given"]},"max_delivery_days":{"type":"integer","minimum":1,"maximum":10},"one_rate_packages":{"minItems":1,"type":"array","items":{"type":"string","enum":["FEDEX_ENVELOPE","FEDEX_PAK","FEDEX_EXTRA_SMALL_BOX","FEDEX_SMALL_BOX","FEDEX_MEDIUM_BOX","FEDEX_LARGE_BOX","FEDEX_EXTRA_LARGE_BOX","FEDEX_TUBE","USPS_FLAT_RATE_ENVELOPE","USPS_LEGAL_FLAT_RATE_ENVELOPE","USPS_PADDED_FLAT_RATE_ENVELOPE","USPS_SMALL_FLAT_RATE_BOX","USPS_MEDIUM_FLAT_RATE_BOX","USPS_LARGE_FLAT_RATE_BOX","UPS_SIMPLE_XS","UPS_SIMPLE_S","UPS_SIMPLE_M","UPS_SIMPLE_L","UPS_SIMPLE_XL"]}}},"required":["to_address","parcel"]}},"service":{"type":"string","minLength":1,"maxLength":64},"max_delivery_days":{"type":"integer","minimum":1,"maximum":10},"one_rate_packages":{"minItems":1,"type":"array","items":{"type":"string","enum":["FEDEX_ENVELOPE","FEDEX_PAK","FEDEX_EXTRA_SMALL_BOX","FEDEX_SMALL_BOX","FEDEX_MEDIUM_BOX","FEDEX_LARGE_BOX","FEDEX_EXTRA_LARGE_BOX","FEDEX_TUBE","USPS_FLAT_RATE_ENVELOPE","USPS_LEGAL_FLAT_RATE_ENVELOPE","USPS_PADDED_FLAT_RATE_ENVELOPE","USPS_SMALL_FLAT_RATE_BOX","USPS_MEDIUM_FLAT_RATE_BOX","USPS_LARGE_FLAT_RATE_BOX","UPS_SIMPLE_XS","UPS_SIMPLE_S","UPS_SIMPLE_M","UPS_SIMPLE_L","UPS_SIMPLE_XL"]}},"apply_rules":{"description":"`false` skips shipping rules for every order that doesn't set its own","type":"boolean"},"carrier":{"description":"Only use this carrier (ID or display name, e.g. `fedex`)","type":"string","minLength":1,"maxLength":64},"carrier_account_id":{"description":"Only use this carrier account","type":"string","maxLength":64,"format":"starts_with","pattern":"^ca_.*"},"one_rate":{"description":"Default `as_given`, unless a shipping rule says otherwise","type":"string","enum":["compare","as_given"]},"label_format":{"default":"PDF","type":"string","enum":["PDF","ZPLII"]}},"required":["shipments"]},"CompareRates":{"$id":"#/components/schemas/CompareRates","type":"object","properties":{"shipments":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"object","properties":{"carrier":{"description":"Only use this carrier (ID or display name, e.g. `fedex`)","type":"string","minLength":1,"maxLength":64},"carrier_account_id":{"description":"Only use this carrier account","type":"string","maxLength":64,"format":"starts_with","pattern":"^ca_.*"},"from_address":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"starts_with","pattern":"^adr_.*"}},"required":["id"],"additionalProperties":false},{"$ref":"#/components/schemas/AddressInput"}]},"to_address":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"starts_with","pattern":"^adr_.*"}},"required":["id"],"additionalProperties":false},{"$ref":"#/components/schemas/AddressInput"}]},"parcel":{"anyOf":[{"type":"object","properties":{"weight":{"type":"number","exclusiveMinimum":0,"maximum":2400,"description":"ounces (FedEx Express limit is 150 lb)"},"predefined_package":{"type":"string","enum":["YOUR_PACKAGING","FEDEX_ENVELOPE","FEDEX_PAK","FEDEX_EXTRA_SMALL_BOX","FEDEX_SMALL_BOX","FEDEX_MEDIUM_BOX","FEDEX_LARGE_BOX","FEDEX_EXTRA_LARGE_BOX","FEDEX_TUBE","USPS_FLAT_RATE_ENVELOPE","USPS_LEGAL_FLAT_RATE_ENVELOPE","USPS_PADDED_FLAT_RATE_ENVELOPE","USPS_SMALL_FLAT_RATE_BOX","USPS_MEDIUM_FLAT_RATE_BOX","USPS_LARGE_FLAT_RATE_BOX","UPS_LETTER","UPS_TUBE","UPS_PAK","UPS_EXPRESS_BOX","UPS_EXPRESS_BOX_SMALL","UPS_EXPRESS_BOX_MEDIUM","UPS_EXPRESS_BOX_LARGE","UPS_SIMPLE_XS","UPS_SIMPLE_S","UPS_SIMPLE_M","UPS_SIMPLE_L","UPS_SIMPLE_XL"]},"length":{"type":"number","exclusiveMinimum":0,"maximum":119},"width":{"type":"number","exclusiveMinimum":0,"maximum":119},"height":{"type":"number","exclusiveMinimum":0,"maximum":119},"preset":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,39}$"}},"required":["preset"],"additionalProperties":false},{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,39}$"},{"$ref":"#/components/schemas/Parcel"}]},"options":{"$ref":"#/components/schemas/ShipmentOptions"},"protection":{"type":"object","properties":{"value":{"type":"string","pattern":"^\\d{1,7}(\\.\\d{1,2})?$"}},"required":["value"],"additionalProperties":false},"order":{"type":"object","properties":{"value":{"description":"What the order is worth, e.g. \"149.00\" (a number works too). Defaults to the sum of the items' `value` × `quantity`","type":["string","number"]},"currency":{"description":"Three-letter currency of `value`. Informational: nothing is converted","type":"string","minLength":3,"maxLength":3},"tags":{"description":"e.g. `[\"fragile\", \"gift\"]`; shipping rules can test for them","maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":64}},"shipping_method":{"description":"What the customer chose at checkout, e.g. `Expedited`","type":"string","minLength":1,"maxLength":100},"shipping_paid":{"description":"What the customer paid for shipping at checkout, e.g. \"12.95\", in `currency`. `max_price` can cap the label at it","type":["string","number"]},"items":{"maxItems":500,"type":"array","items":{"type":"object","properties":{"sku":{"type":"string","minLength":1,"maxLength":100},"quantity":{"default":1,"type":"integer","minimum":1,"maximum":100000},"value":{"description":"The price of one unit","type":["string","number"]}},"required":["sku"],"additionalProperties":false}}},"additionalProperties":false,"description":"What's being ordered. Shipping rules can look at it; nothing here is sent to the carrier. Shopify's `total_price`, `tags`, shipping line and line items map onto it"},"apply_rules":{"description":"`false` skips shipping rules for this request. Defaults to true","type":"boolean"},"customs_info":{"description":"The customs declaration, with EasyPost's field names. Required when the parcel crosses a customs border: the origin and destination countries differ, other than between the US and its territories","$ref":"#/components/schemas/CustomsInfoInput"},"reference":{"type":"string","minLength":1,"maxLength":255},"service":{"type":"string","minLength":1,"maxLength":64},"one_rate":{"type":"string","enum":["compare","as_given"]},"max_delivery_days":{"type":"integer","minimum":1,"maximum":10},"one_rate_packages":{"minItems":1,"type":"array","items":{"type":"string","enum":["FEDEX_ENVELOPE","FEDEX_PAK","FEDEX_EXTRA_SMALL_BOX","FEDEX_SMALL_BOX","FEDEX_MEDIUM_BOX","FEDEX_LARGE_BOX","FEDEX_EXTRA_LARGE_BOX","FEDEX_TUBE","USPS_FLAT_RATE_ENVELOPE","USPS_LEGAL_FLAT_RATE_ENVELOPE","USPS_PADDED_FLAT_RATE_ENVELOPE","USPS_SMALL_FLAT_RATE_BOX","USPS_MEDIUM_FLAT_RATE_BOX","USPS_LARGE_FLAT_RATE_BOX","UPS_SIMPLE_XS","UPS_SIMPLE_S","UPS_SIMPLE_M","UPS_SIMPLE_L","UPS_SIMPLE_XL"]}}},"required":["to_address","parcel"]}},"service":{"type":"string","minLength":1,"maxLength":64},"max_delivery_days":{"type":"integer","minimum":1,"maximum":10},"one_rate_packages":{"minItems":1,"type":"array","items":{"type":"string","enum":["FEDEX_ENVELOPE","FEDEX_PAK","FEDEX_EXTRA_SMALL_BOX","FEDEX_SMALL_BOX","FEDEX_MEDIUM_BOX","FEDEX_LARGE_BOX","FEDEX_EXTRA_LARGE_BOX","FEDEX_TUBE","USPS_FLAT_RATE_ENVELOPE","USPS_LEGAL_FLAT_RATE_ENVELOPE","USPS_PADDED_FLAT_RATE_ENVELOPE","USPS_SMALL_FLAT_RATE_BOX","USPS_MEDIUM_FLAT_RATE_BOX","USPS_LARGE_FLAT_RATE_BOX","UPS_SIMPLE_XS","UPS_SIMPLE_S","UPS_SIMPLE_M","UPS_SIMPLE_L","UPS_SIMPLE_XL"]}},"apply_rules":{"description":"`false` skips shipping rules for every order that doesn't set its own","type":"boolean"},"carrier":{"description":"Only use this carrier (ID or display name, e.g. `fedex`)","type":"string","minLength":1,"maxLength":64},"carrier_account_id":{"description":"Only use this carrier account","type":"string","maxLength":64,"format":"starts_with","pattern":"^ca_.*"},"one_rate":{"description":"Default `compare`, unless a shipping rule says otherwise","type":"string","enum":["compare","as_given"]},"label_format":{"type":"string","enum":["PDF","ZPLII"]}},"required":["shipments"]},"MergeLabels":{"$id":"#/components/schemas/MergeLabels","type":"object","properties":{"shipment_ids":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"string","maxLength":64,"format":"starts_with","pattern":"^shp_.*"}}},"required":["shipment_ids"]},"SaveDraft":{"$id":"#/components/schemas/SaveDraft","type":"object","properties":{"payload":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["payload"]},"CreateClaim":{"$id":"#/components/schemas/CreateClaim","type":"object","properties":{"reason":{"type":"string","enum":["lost","damaged","stolen","other"]},"description":{"type":"string","minLength":1,"maxLength":2000}},"required":["reason"]},"UpdateClaim":{"$id":"#/components/schemas/UpdateClaim","type":"object","properties":{"status":{"type":"string","enum":["approved","denied"]},"resolution":{"type":"string","enum":["refund","reship"]},"amount":{"type":"string","pattern":"^\\d{1,7}(\\.\\d{1,2})?$"},"notes":{"type":"string","maxLength":2000}}},"UpdateSettings":{"$id":"#/components/schemas/UpdateSettings","type":"object","properties":{"default_from_address":{"anyOf":[{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"starts_with","pattern":"^adr_.*"}},"required":["id"],"additionalProperties":false},{"$ref":"#/components/schemas/AddressInput"}]},{"type":"null"}]},"parcel_presets":{"type":"object","propertyNames":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,39}$"},"additionalProperties":{"$ref":"#/components/schemas/ParcelPreset"}},"protection":{"type":"object","properties":{"enabled":{"type":"boolean"},"percent":{"type":"number","minimum":0,"maximum":100},"minimum":{"type":"string","pattern":"^\\d{1,7}(\\.\\d{1,2})?$"},"max_value":{"type":"string","pattern":"^\\d{1,7}(\\.\\d{1,2})?$"},"default_on":{"default":false,"type":"boolean"}},"required":["enabled","percent","minimum","max_value"],"additionalProperties":false},"emails":{"type":"object","properties":{"enabled":{"type":"boolean"}},"required":["enabled"],"additionalProperties":false},"branding":{"type":"object","properties":{"store_name":{"anyOf":[{"type":"string","minLength":1,"maxLength":80},{"type":"null"}]},"accent_color":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}]},"store_url":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}]},"support_email":{"anyOf":[{"type":"string","maxLength":254},{"type":"null"}]},"theme":{"type":"string","enum":["light","device"]}},"additionalProperties":false}}},"CreateTracker":{"$id":"#/components/schemas/CreateTracker","type":"object","properties":{"tracking_code":{"type":"string","minLength":1,"maxLength":64},"carrier":{"description":"Defaults to the carrier the number's format points to; numbers that match no known format are tracked with FedEx","type":"string","minLength":1,"maxLength":64}},"required":["tracking_code"]},"CreateCarrierAccount":{"$id":"#/components/schemas/CreateCarrierAccount","type":"object","properties":{"carrier":{"type":"string","minLength":1,"maxLength":64,"description":"A carrier ID or display name, e.g. `fedex` or `FedEx`"},"description":{"type":"string","maxLength":100},"settings":{"default":{},"description":"Non-secret settings, returned as given. For FedEx: `account_number` and `environment` (`sandbox` or `production`)","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","maxLength":200}},"credentials":{"description":"Write-only, encrypted at rest and never returned. For FedEx: `client_id`, `client_secret`, and optionally `track_client_id`, `track_client_secret`, `webhook_secret`","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","maxLength":500}},"enabled":{"default":true,"type":"boolean"}},"required":["carrier"]},"UpdateCarrierAccount":{"$id":"#/components/schemas/UpdateCarrierAccount","type":"object","properties":{"description":{"type":"string","maxLength":100},"settings":{"description":"Merged into the existing settings","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","maxLength":200}},"credentials":{"description":"Replaces the stored credentials as a whole","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","maxLength":500}},"enabled":{"description":"A disabled account stops quoting and buying; its existing labels and trackers keep working","type":"boolean"}}},"TestCarrierAccount":{"$id":"#/components/schemas/TestCarrierAccount","type":"object","properties":{"carrier":{"type":"string","minLength":1,"maxLength":64,"description":"A carrier ID or display name, e.g. `fedex` or `FedEx`"},"settings":{"default":{},"description":"Non-secret settings, returned as given. For FedEx: `account_number` and `environment` (`sandbox` or `production`)","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","maxLength":200}},"credentials":{"description":"Write-only, encrypted at rest and never returned. For FedEx: `client_id`, `client_secret`, and optionally `track_client_id`, `track_client_secret`, `webhook_secret`","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","maxLength":500}}},"required":["carrier"],"description":"The same fields as creating an account. Nothing is stored; the credentials are used for this test only"},"CreateWebhook":{"$id":"#/components/schemas/CreateWebhook","type":"object","properties":{"url":{"type":"string","maxLength":2048}},"required":["url"]},"UpdateWebhook":{"$id":"#/components/schemas/UpdateWebhook","type":"object","properties":{"url":{"type":"string","maxLength":2048},"disabled":{"type":"boolean","description":"A disabled webhook gets no new events, and its queued deliveries fail instead of being sent"}},"additionalProperties":false},"RuleAction":{"$id":"#/components/schemas/RuleAction","oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"set_signature"},"signature":{"type":"string","enum":["none","indirect","direct","adult"]}},"required":["type","signature"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"set_declared_value"},"value":{"type":["string","number"]},"percent_of_order_value":{"type":"number","exclusiveMinimum":0,"maximum":100}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"add_protection"},"value":{"type":["string","number"]},"percent_of_order_value":{"type":"number","exclusiveMinimum":0,"maximum":100}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"set_saturday_delivery"},"enabled":{"default":true,"type":"boolean"}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"use_preset"},"preset":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,39}$"}},"required":["type","preset"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"one_rate"},"mode":{"type":"string","enum":["compare","force","off"]}},"required":["type","mode"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"set_from_address"},"address_id":{"type":"string","pattern":"^adr_[A-Za-z0-9]+$"}},"required":["type","address_id"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"exclude_carriers"},"carriers":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":64}}},"required":["type","carriers"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"only_carriers"},"carriers":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":64}}},"required":["type","carriers"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"exclude_services"},"services":{"minItems":1,"maxItems":30,"type":"array","items":{"type":"string","minLength":1,"maxLength":64}}},"required":["type","services"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"only_services"},"services":{"minItems":1,"maxItems":30,"type":"array","items":{"type":"string","minLength":1,"maxLength":64}}},"required":["type","services"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"max_delivery_days"},"days":{"type":"integer","minimum":1,"maximum":30}},"required":["type","days"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"max_price"},"amount":{"type":["string","number"]},"percent_of_order_value":{"type":"number","exclusiveMinimum":0,"maximum":1000},"over_shipping_paid":{"description":"Dollars over `order.shipping_paid`; \"0.00\" caps at what the customer paid","type":["string","number"]},"if_none_left":{"description":"`remove` (default) removes over-cap rates even if none are left; `relax` removes none when the cap would leave no rate","type":"string","enum":["remove","relax"]}},"required":["type"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"pick"},"service":{"type":"string","minLength":1,"maxLength":64,"description":"cheapest, fastest, best_value, or a service code"}},"required":["type","service"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"prefer_carrier"},"carrier":{"type":"string","minLength":1,"maxLength":64},"within":{"type":["string","number"]}},"required":["type","carrier"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"add_tag"},"tag":{"type":"string","minLength":1,"maxLength":64}},"required":["type","tag"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"add_note"},"note":{"type":"string","minLength":1,"maxLength":500}},"required":["type","note"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"block"},"message":{"type":"string","minLength":1,"maxLength":300}},"required":["type","message"],"additionalProperties":false}]},"CreateRule":{"$id":"#/components/schemas/CreateRule","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"description":{"default":"","type":"string","maxLength":500},"enabled":{"default":true,"type":"boolean"},"when":{"$ref":"#/components/schemas/RuleCondition"},"then":{"minItems":1,"maxItems":20,"type":"array","items":{"$ref":"#/components/schemas/RuleAction"}},"stop_processing":{"default":false,"type":"boolean"},"position":{"description":"1-based; defaults to last","type":"integer","minimum":1,"maximum":50}},"required":["name","when","then"],"additionalProperties":false},"UpdateRule":{"$id":"#/components/schemas/UpdateRule","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"description":{"type":"string","maxLength":500},"enabled":{"type":"boolean"},"when":{"$ref":"#/components/schemas/RuleCondition"},"then":{"minItems":1,"maxItems":20,"type":"array","items":{"$ref":"#/components/schemas/RuleAction"}},"stop_processing":{"type":"boolean"},"position":{"type":"integer","minimum":1,"maximum":50}},"additionalProperties":false},"ReorderRules":{"$id":"#/components/schemas/ReorderRules","type":"object","properties":{"rule_ids":{"maxItems":50,"type":"array","items":{"type":"string","maxLength":64}}},"required":["rule_ids"],"additionalProperties":false},"TestRules":{"$id":"#/components/schemas/TestRules","type":"object","properties":{"input":{"type":"object","properties":{"carrier":{"description":"Only use this carrier (ID or display name, e.g. `fedex`)","type":"string","minLength":1,"maxLength":64},"carrier_account_id":{"description":"Only use this carrier account","type":"string","maxLength":64,"format":"starts_with","pattern":"^ca_.*"},"from_address":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"starts_with","pattern":"^adr_.*"}},"required":["id"],"additionalProperties":false},{"$ref":"#/components/schemas/AddressInput"}]},"to_address":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","format":"starts_with","pattern":"^adr_.*"}},"required":["id"],"additionalProperties":false},{"$ref":"#/components/schemas/AddressInput"}]},"parcel":{"anyOf":[{"type":"object","properties":{"weight":{"type":"number","exclusiveMinimum":0,"maximum":2400,"description":"ounces (FedEx Express limit is 150 lb)"},"predefined_package":{"type":"string","enum":["YOUR_PACKAGING","FEDEX_ENVELOPE","FEDEX_PAK","FEDEX_EXTRA_SMALL_BOX","FEDEX_SMALL_BOX","FEDEX_MEDIUM_BOX","FEDEX_LARGE_BOX","FEDEX_EXTRA_LARGE_BOX","FEDEX_TUBE","USPS_FLAT_RATE_ENVELOPE","USPS_LEGAL_FLAT_RATE_ENVELOPE","USPS_PADDED_FLAT_RATE_ENVELOPE","USPS_SMALL_FLAT_RATE_BOX","USPS_MEDIUM_FLAT_RATE_BOX","USPS_LARGE_FLAT_RATE_BOX","UPS_LETTER","UPS_TUBE","UPS_PAK","UPS_EXPRESS_BOX","UPS_EXPRESS_BOX_SMALL","UPS_EXPRESS_BOX_MEDIUM","UPS_EXPRESS_BOX_LARGE","UPS_SIMPLE_XS","UPS_SIMPLE_S","UPS_SIMPLE_M","UPS_SIMPLE_L","UPS_SIMPLE_XL"]},"length":{"type":"number","exclusiveMinimum":0,"maximum":119},"width":{"type":"number","exclusiveMinimum":0,"maximum":119},"height":{"type":"number","exclusiveMinimum":0,"maximum":119},"preset":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,39}$"}},"required":["preset"],"additionalProperties":false},{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,39}$"},{"$ref":"#/components/schemas/Parcel"}]},"options":{"$ref":"#/components/schemas/ShipmentOptions"},"protection":{"type":"object","properties":{"value":{"type":"string","pattern":"^\\d{1,7}(\\.\\d{1,2})?$"}},"required":["value"],"additionalProperties":false},"order":{"type":"object","properties":{"value":{"description":"What the order is worth, e.g. \"149.00\" (a number works too). Defaults to the sum of the items' `value` × `quantity`","type":["string","number"]},"currency":{"description":"Three-letter currency of `value`. Informational: nothing is converted","type":"string","minLength":3,"maxLength":3},"tags":{"description":"e.g. `[\"fragile\", \"gift\"]`; shipping rules can test for them","maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":64}},"shipping_method":{"description":"What the customer chose at checkout, e.g. `Expedited`","type":"string","minLength":1,"maxLength":100},"shipping_paid":{"description":"What the customer paid for shipping at checkout, e.g. \"12.95\", in `currency`. `max_price` can cap the label at it","type":["string","number"]},"items":{"maxItems":500,"type":"array","items":{"type":"object","properties":{"sku":{"type":"string","minLength":1,"maxLength":100},"quantity":{"default":1,"type":"integer","minimum":1,"maximum":100000},"value":{"description":"The price of one unit","type":["string","number"]}},"required":["sku"],"additionalProperties":false}}},"additionalProperties":false,"description":"What's being ordered. Shipping rules can look at it; nothing here is sent to the carrier. Shopify's `total_price`, `tags`, shipping line and line items map onto it"},"apply_rules":{"description":"`false` skips shipping rules for this request. Defaults to true","type":"boolean"},"customs_info":{"description":"The customs declaration, with EasyPost's field names. Required when the parcel crosses a customs border: the origin and destination countries differ, other than between the US and its territories","$ref":"#/components/schemas/CustomsInfoInput"},"reference":{"type":"string","minLength":1,"maxLength":255},"service":{"description":"A service the caller asked for (beats a rule's `pick`), or `cheapest` / `fastest` / `best_value` as a batch would","type":"string","maxLength":64},"source":{"description":"Defaults to `api`","type":"string","enum":["api","admin","batch"]}},"required":["to_address","parcel"]},"shipment_id":{"type":"string","maxLength":64,"format":"starts_with","pattern":"^shp_.*"},"rules":{"description":"Rules you haven't saved. They replace the saved rules for this test","maxItems":50,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"description":{"default":"","type":"string","maxLength":500},"enabled":{"default":true,"type":"boolean"},"when":{"$ref":"#/components/schemas/RuleCondition"},"then":{"minItems":1,"maxItems":20,"type":"array","items":{"$ref":"#/components/schemas/RuleAction"}},"stop_processing":{"default":false,"type":"boolean"},"id":{"type":"string","maxLength":64}},"required":["name","when","then"],"additionalProperties":false}},"quote":{"default":false,"description":"Also quote with the carriers (the mock ones in test mode) and show the rates that survive","type":"boolean"}},"additionalProperties":false},"DraftRule":{"$id":"#/components/schemas/DraftRule","type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":1000,"description":"What the rule should do, in plain English"},"existing_rule_id":{"description":"Edit this saved rule instead of drafting a new one","type":"string","maxLength":64}},"required":["text"],"additionalProperties":false},"CreateApiKey":{"$id":"#/components/schemas/CreateApiKey","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"mode":{"default":"live","type":"string","enum":["live","test"]},"scopes":{"description":"Defaults to full access, `[\"*\"]`. `shipments:write` includes `shipments:read` and `rates:read`","anyOf":[{"type":"array","prefixItems":[{"type":"string","const":"*"}],"items":false,"minItems":1,"maxItems":1},{"minItems":1,"maxItems":10,"type":"array","items":{"type":"string","enum":["rates:read","shipments:read","shipments:write","protection:manage","settings:write","webhooks:manage","rules:read","rules:write","print:read","print:write"]}}]},"daily_label_limit":{"type":"integer","minimum":1,"maximum":1000000,"description":"Labels per UTC day"},"daily_spend_limit":{"description":"Dollars of label charges per UTC day","type":"string","pattern":"^\\d{1,7}(\\.\\d{1,2})?$"},"expires_at":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},"required":["name"]},"UpdateApiKey":{"$id":"#/components/schemas/UpdateApiKey","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"scopes":{"description":"`[\"*\"]` is full access","anyOf":[{"type":"array","prefixItems":[{"type":"string","const":"*"}],"items":false,"minItems":1,"maxItems":1},{"minItems":1,"maxItems":10,"type":"array","items":{"type":"string","enum":["rates:read","shipments:read","shipments:write","protection:manage","settings:write","webhooks:manage","rules:read","rules:write","print:read","print:write"]}}]},"daily_label_limit":{"anyOf":[{"type":"integer","minimum":1,"maximum":1000000,"description":"Labels per UTC day"},{"type":"null"}],"description":"Labels per UTC day; `null` removes the limit"},"daily_spend_limit":{"anyOf":[{"description":"Dollars of label charges per UTC day","type":"string","pattern":"^\\d{1,7}(\\.\\d{1,2})?$"},{"type":"null"}],"description":"Dollars of label charges per UTC day; `null` removes the limit"},"expires_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}],"description":"`null` makes the key never expire"}},"additionalProperties":false},"InviteMember":{"$id":"#/components/schemas/InviteMember","type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"role":{"type":"string","enum":["owner","admin","member","viewer"],"description":"`owner`, `admin`, `member` (shipping staff) or `viewer` (read-only)"}},"required":["email","role"]},"ChangeMemberRole":{"$id":"#/components/schemas/ChangeMemberRole","type":"object","properties":{"role":{"type":"string","enum":["owner","admin","member","viewer"]}},"required":["role"]},"RenameOrganization":{"$id":"#/components/schemas/RenameOrganization","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100}},"required":["name"]},"Bootstrap":{"$id":"#/components/schemas/Bootstrap","type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"name":{"type":"string","minLength":1,"maxLength":100},"password":{"description":"Required unless a user with this email already exists","type":"string","minLength":10,"maxLength":128}},"required":["email","name"]},"CreateOrganization":{"$id":"#/components/schemas/CreateOrganization","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"slug":{"type":"string","maxLength":48,"pattern":"^[a-z0-9]+(-[a-z0-9]+)*$"},"owner":{"$ref":"#/components/schemas/Bootstrap"}},"required":["name","owner"]},"Signup":{"$id":"#/components/schemas/Signup","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"email":{"type":"string","maxLength":254},"password":{"type":"string","minLength":10,"maxLength":128},"organization_name":{"type":"string","minLength":1,"maxLength":100,"description":"The company or store"},"turnstile_token":{"type":"string","maxLength":2048}},"required":["name","email","password","organization_name"]},"NewOrganization":{"$id":"#/components/schemas/NewOrganization","type":"object","properties":{"organization_name":{"type":"string","minLength":1,"maxLength":100},"turnstile_token":{"type":"string","maxLength":2048}},"required":["organization_name"]},"CreatePrintLocation":{"$id":"#/components/schemas/CreatePrintLocation","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"is_default":{"description":"Make it the location jobs go to when they name none","type":"boolean"}},"required":["name"]},"UpdatePrintLocation":{"$id":"#/components/schemas/UpdatePrintLocation","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"is_default":{"description":"Only `true`: to change the default, make another location the default","type":"boolean","const":true},"failover":{"description":"Move jobs to another healthy printer with the same role here when theirs is out of paper, jammed, open, paused, offline or stuck. On by default","type":"boolean"}}},"CreatePairingCode":{"$id":"#/components/schemas/CreatePairingCode","type":"object","properties":{"location_id":{"description":"The location the station joins. Defaults to the default location, created as \"Main\" if there is none","type":"string","maxLength":64,"format":"starts_with","pattern":"^ploc_.*"},"name":{"description":"The station's name. Defaults to the computer's name","type":"string","minLength":1,"maxLength":80}}},"UpdatePrintStation":{"$id":"#/components/schemas/UpdatePrintStation","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"location_id":{"description":"Moves the station and its printers","type":"string","maxLength":64,"format":"starts_with","pattern":"^ploc_.*"},"paused":{"description":"A paused station keeps its connection but gets no jobs; they wait in `queued`","type":"boolean"},"auto_update":{"description":"Let the agent install new releases by itself, between jobs. On by default","type":"boolean"}}},"UpdatePrinter":{"$id":"#/components/schemas/UpdatePrinter","type":"object","properties":{"name":{"description":"`null` goes back to the name the computer reports","anyOf":[{"type":"string","minLength":1,"maxLength":80},{"type":"null"}]},"roles":{"description":"What it prints: `label` (4×6), `slip` (packing slips), `letter` (Letter paper). A printer can hold several","maxItems":3,"type":"array","items":{"type":"string","enum":["label","slip","letter"]}},"default_for":{"description":"Roles this printer is the location's default for; each must be in `roles`. Takes the default over from any other printer","maxItems":3,"type":"array","items":{"type":"string","enum":["label","slip","letter"]}},"languages":{"description":"What it takes: `pdf`, `zpl` or both. Overrides what the station detected; `null` goes back to it. Network printers can't go back to `null`","anyOf":[{"minItems":1,"maxItems":2,"type":"array","items":{"type":"string","enum":["pdf","zpl"]}},{"type":"null"}]},"host":{"description":"Network printers only","type":"string","minLength":1,"maxLength":253,"pattern":"^(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*\\.?|\\[?[0-9A-Fa-f:.]+(?:%[\\w.-]+)?\\]?)$"},"port":{"description":"Network printers only","type":"integer","minimum":1,"maximum":65535},"protocol":{"description":"Network printers only","type":"string","enum":["raw9100","ipp"]},"path":{"description":"Network printers using IPP only","anyOf":[{"type":"string","maxLength":200,"pattern":"^\\/[\\w./~%-]{0,200}$"},{"type":"null"}]}}},"CreateNetworkPrinter":{"$id":"#/components/schemas/CreateNetworkPrinter","type":"object","properties":{"station_id":{"type":"string","maxLength":64,"format":"starts_with","pattern":"^pst_.*","description":"The station that reaches the printer; it must be on the printer's network"},"name":{"type":"string","minLength":1,"maxLength":80},"host":{"description":"IP address or host name, e.g. `192.168.1.50` or `ZD421-ABC.local`","type":"string","minLength":1,"maxLength":253,"pattern":"^(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*\\.?|\\[?[0-9A-Fa-f:.]+(?:%[\\w.-]+)?\\]?)$"},"protocol":{"default":"raw9100","description":"`raw9100`: the bytes go straight to the port (JetDirect/AppSocket). `ipp`: an IPP Print-Job","type":"string","enum":["raw9100","ipp"]},"port":{"description":"Defaults to 9100 for `raw9100` and 631 for `ipp`","type":"integer","minimum":1,"maximum":65535},"path":{"description":"IPP only; defaults to `/ipp/print`","type":"string","maxLength":200,"pattern":"^\\/[\\w./~%-]{0,200}$"},"languages":{"description":"What it takes. Defaults to `[\"zpl\"]` for `raw9100` and `[\"pdf\"]` for `ipp`","minItems":1,"maxItems":2,"type":"array","items":{"type":"string","enum":["pdf","zpl"]}},"roles":{"maxItems":3,"type":"array","items":{"type":"string","enum":["label","slip","letter"]}}},"required":["station_id","name","host"]},"CreatePrintJob":{"$id":"#/components/schemas/CreatePrintJob","type":"object","properties":{"kind":{"description":"What is printed; it picks the printer when `printer_id` and `role` are absent. Defaults to `label` for shipment and batch sources, else `document`","type":"string","enum":["label","slip","packing_list","invoice","document"]},"printer_id":{"type":"string","maxLength":64,"format":"starts_with","pattern":"^prn_.*"},"role":{"description":"Print on the location's default printer for this role, instead of the one `kind` maps to","type":"string","enum":["label","slip","letter"]},"location_id":{"description":"Where to print; defaults to the default location","type":"string","maxLength":64,"format":"starts_with","pattern":"^ploc_.*"},"title":{"type":"string","minLength":1,"maxLength":120},"copies":{"default":1,"type":"integer","minimum":1,"maximum":20},"paper":{"default":"auto","description":"`auto` uses the first page's size, then the printer's role","type":"string","enum":["auto","4x6","letter"]},"fit":{"default":"actual","description":"`actual` prints at 100%, which labels need; `fit` scales the page to the paper","type":"string","enum":["actual","fit"]},"priority":{"default":0,"description":"Higher prints first","type":"integer","minimum":-100,"maximum":100},"tags":{"default":[],"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":40}},"idempotency_key":{"description":"A second job with the same key returns the first instead. Unique per organization and mode","type":"string","minLength":1,"maxLength":255},"file_base64":{"type":"string","minLength":1,"description":"A PDF, PNG, JPEG or ZPL file, base64-encoded, up to 20 MB decoded. Images are placed on one page of `paper`; ZPL goes raw to a printer that takes it"},"content_type":{"description":"Of `file_base64`; detected from the bytes when omitted. Send `application/x-zpl` for ZPL that doesn't start with `^` or `~`","type":"string","enum":["application/pdf","image/png","image/jpeg","application/x-zpl"]},"shipment_id":{"type":"string","maxLength":64,"format":"starts_with","pattern":"^shp_.*","description":"Prints the shipment's label (PDF, PNG or ZPL)"},"shipment_ids":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"string","maxLength":64,"format":"starts_with","pattern":"^shp_.*"},"description":"Prints these shipments' labels as one job, in order; all PDF or all ZPL"},"batch_id":{"type":"string","maxLength":64,"format":"starts_with","pattern":"^bat_.*","description":"Prints every label bought in the batch as one job"}}},"PrintJobOptions":{"$id":"#/components/schemas/PrintJobOptions","type":"object","properties":{"kind":{"description":"What is printed; it picks the printer when `printer_id` and `role` are absent. Defaults to `label` for shipment and batch sources, else `document`","type":"string","enum":["label","slip","packing_list","invoice","document"]},"printer_id":{"type":"string","maxLength":64,"format":"starts_with","pattern":"^prn_.*"},"role":{"description":"Print on the location's default printer for this role, instead of the one `kind` maps to","type":"string","enum":["label","slip","letter"]},"location_id":{"description":"Where to print; defaults to the default location","type":"string","maxLength":64,"format":"starts_with","pattern":"^ploc_.*"},"title":{"type":"string","minLength":1,"maxLength":120},"copies":{"default":1,"type":"integer","minimum":1,"maximum":20},"paper":{"default":"auto","description":"`auto` uses the first page's size, then the printer's role","type":"string","enum":["auto","4x6","letter"]},"fit":{"default":"actual","description":"`actual` prints at 100%, which labels need; `fit` scales the page to the paper","type":"string","enum":["actual","fit"]},"priority":{"default":0,"description":"Higher prints first","type":"integer","minimum":-100,"maximum":100},"tags":{"default":[],"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":40}},"idempotency_key":{"description":"A second job with the same key returns the first instead. Unique per organization and mode","type":"string","minLength":1,"maxLength":255}}},"ReprintJob":{"$id":"#/components/schemas/ReprintJob","type":"object","properties":{"printer_id":{"description":"Defaults to the original printer","type":"string","maxLength":64,"format":"starts_with","pattern":"^prn_.*"},"copies":{"type":"integer","minimum":1,"maximum":20}}},"PrintTestPage":{"$id":"#/components/schemas/PrintTestPage","type":"object","properties":{"paper":{"description":"Defaults to 4×6 unless the printer only takes Letter or its roles are only `letter`","type":"string","enum":["4x6","letter"]}}},"UpdatePrintSettings":{"$id":"#/components/schemas/UpdatePrintSettings","type":"object","properties":{"alerts":{"type":"object","properties":{"enabled":{"description":"Email when a printer has a problem or a station goes offline. On by default","type":"boolean"},"notify_admins":{"description":"Send them to the organization's owners and admins. On by default","type":"boolean"},"recipients":{"description":"Other addresses to send them to","maxItems":10,"type":"array","items":{"type":"string","maxLength":254,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"problem_minutes":{"description":"How long a printer problem lasts before the email. Default 2","type":"integer","minimum":1,"maximum":120},"business_hours":{"description":"Only email about offline stations in these hours; `null` (the default) is any time. Printer problems are always emailed","anyOf":[{"type":"object","properties":{"timezone":{"type":"string","minLength":1,"maxLength":64,"description":"An IANA time zone, e.g. `America/New_York`"},"days":{"description":"0 is Sunday","minItems":1,"maxItems":7,"type":"array","items":{"type":"integer","minimum":0,"maximum":6}},"start":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$","description":"`HH:MM`, 24-hour"},"end":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$","description":"`HH:MM`, 24-hour; earlier than `start` runs past midnight"}},"required":["timezone","days","start","end"]},{"type":"null"}]}}}}},"RuleCondition":{"description":"A test, or an `all` / `any` / `not` group of conditions, nested up to 5 levels. `{ \"all\": [] }` matches everything.\n\nExamples:\n\n```json\n{ \"all\": [ { \"field\": \"to.state\", \"op\": \"in\", \"value\": [\"HI\", \"AK\"] }, { \"field\": \"parcel.weight\", \"op\": \"gt\", \"value\": 2, \"unit\": \"lb\" } ] }\n{ \"any\": [ { \"field\": \"to.po_box\", \"op\": \"eq\", \"value\": true }, { \"field\": \"to.military\", \"op\": \"eq\", \"value\": true } ] }\n{ \"all\": [ { \"field\": \"order.value\", \"op\": \"gte\", \"value\": \"100.00\" }, { \"not\": { \"field\": \"order.tags\", \"op\": \"contains\", \"value\": \"wholesale\" } } ] }\n```\n\nA missing fact never satisfies a test, except `neq`, `not_in`, `not_contains` and `not_exists`, which a missing value satisfies. Text is compared ignoring case.\n\n| Field | Type | Operators | What it is |\n| --- | --- | --- | --- |\n| `to.country` | country | `eq` `neq` `in` `not_in` `exists` `not_exists` | Two-letter country code of the destination, e.g. US. Example: `{\"field\":\"to.country\",\"op\":\"neq\",\"value\":\"US\"}` |\n| `to.state` | state | `eq` `neq` `in` `not_in` `exists` `not_exists` | State or province of the destination, e.g. HI. Compared ignoring case. Example: `{\"field\":\"to.state\",\"op\":\"in\",\"value\":[\"HI\",\"AK\",\"PR\"]}` |\n| `to.zip` | zip | `eq` `neq` `in` `not_in` `starts_with` `between` `matches_any_zip` `exists` `not_exists` | Postal code of the destination. US ZIP+4 is cut to the first five digits. Supports prefixes and ranges. Example: `{\"field\":\"to.zip\",\"op\":\"matches_any_zip\",\"value\":[\"967\",\"96701-96899\"]}` |\n| `to.city` | text | `eq` `neq` `in` `not_in` `contains` `not_contains` `starts_with` `exists` `not_exists` | City of the destination. Example: `{\"field\":\"to.city\",\"op\":\"eq\",\"value\":\"Honolulu\"}` |\n| `to.residential` | boolean | `eq` `neq` `exists` `not_exists` | Whether the destination is a home. Known when you send `residential`, the saved address says so, or the carrier has classified it (the check runs first when a rule needs it). Example: `{\"field\":\"to.residential\",\"op\":\"eq\",\"value\":true}` |\n| `to.po_box` | boolean | `eq` `neq` | Whether the street line is a PO box (P.O. Box, PO Box, POB, Post Office Box). Example: `{\"field\":\"to.po_box\",\"op\":\"eq\",\"value\":true}` |\n| `to.military` | boolean | `eq` `neq` | Whether the destination is an APO, FPO or DPO address: state AA, AE or AP, or one of those as the city. Example: `{\"field\":\"to.military\",\"op\":\"eq\",\"value\":true}` |\n| `to.company` | text | `eq` `neq` `in` `not_in` `contains` `not_contains` `starts_with` `exists` `not_exists` | The recipient's company. Use `exists` and `not_exists` to tell businesses from people. Example: `{\"field\":\"to.company\",\"op\":\"exists\"}` |\n| `from.state` | state | `eq` `neq` `in` `not_in` `exists` `not_exists` | State of the origin: the from address you sent, or your default from address. Example: `{\"field\":\"from.state\",\"op\":\"eq\",\"value\":\"TN\"}` |\n| `from.zip` | zip | `eq` `neq` `in` `not_in` `starts_with` `between` `matches_any_zip` `exists` `not_exists` | Postal code of the origin. Example: `{\"field\":\"from.zip\",\"op\":\"starts_with\",\"value\":\"381\"}` |\n| `from.address_id` | id | `eq` `neq` `in` `not_in` `exists` `not_exists` | The saved address ID (adr_…) the shipment ships from. Only set when the origin is a saved address. Example: `{\"field\":\"from.address_id\",\"op\":\"eq\",\"value\":\"adr_01a131ca1cc83766d0ac435ef\"}` |\n| `parcel.weight` | weight | `eq` `neq` `gt` `gte` `lt` `lte` `between` | Weight of the package. Give the value in oz, lb, g or kg (default oz); it is compared in ounces. Example: `{\"field\":\"parcel.weight\",\"op\":\"gt\",\"value\":20,\"unit\":\"lb\"}` |\n| `parcel.length` | length | `eq` `neq` `gt` `gte` `lt` `lte` `between` `exists` `not_exists` | Length in inches (or cm). Missing when the package has no dimensions, e.g. carrier packaging. Example: `{\"field\":\"parcel.length\",\"op\":\"gt\",\"value\":24,\"unit\":\"in\"}` |\n| `parcel.width` | length | `eq` `neq` `gt` `gte` `lt` `lte` `between` `exists` `not_exists` | Width in inches (or cm). Example: `{\"field\":\"parcel.width\",\"op\":\"gt\",\"value\":12,\"unit\":\"in\"}` |\n| `parcel.height` | length | `eq` `neq` `gt` `gte` `lt` `lte` `between` `exists` `not_exists` | Height in inches (or cm). Example: `{\"field\":\"parcel.height\",\"op\":\"lte\",\"value\":6,\"unit\":\"in\"}` |\n| `parcel.girth` | length | `eq` `neq` `gt` `gte` `lt` `lte` `between` `exists` `not_exists` | Twice the sum of the two shortest sides, in inches (or cm). Needs all three dimensions. Example: `{\"field\":\"parcel.girth\",\"op\":\"gt\",\"value\":50,\"unit\":\"in\"}` |\n| `parcel.longest_side` | length | `eq` `neq` `gt` `gte` `lt` `lte` `between` `exists` `not_exists` | The longest of the three dimensions, in inches (or cm). Needs all three dimensions. Example: `{\"field\":\"parcel.longest_side\",\"op\":\"gte\",\"value\":30,\"unit\":\"in\"}` |\n| `parcel.preset` | text | `eq` `neq` `in` `not_in` `contains` `not_contains` `starts_with` `exists` `not_exists` | The name of the parcel preset the request used. Missing when the parcel was sent in full. Example: `{\"field\":\"parcel.preset\",\"op\":\"eq\",\"value\":\"small-box\"}` |\n| `parcel.packaging` | text | `eq` `neq` `in` `not_in` `contains` `not_contains` `starts_with` `exists` `not_exists` | The carrier packaging code, e.g. FEDEX_MEDIUM_BOX. YOUR_PACKAGING when the shipment goes in your own box. Example: `{\"field\":\"parcel.packaging\",\"op\":\"starts_with\",\"value\":\"FEDEX_\"}` |\n| `order.value` | money | `eq` `neq` `gt` `gte` `lt` `lte` `between` `exists` `not_exists` | What the order is worth, in dollars: `order.value`, or the sum of the items' `value` × `quantity`. Missing when neither is sent. Example: `{\"field\":\"order.value\",\"op\":\"gte\",\"value\":\"100.00\"}` |\n| `order.currency` | text | `eq` `neq` `in` `not_in` `contains` `not_contains` `starts_with` `exists` `not_exists` | Three-letter currency of `order.value`. Values are compared as given; nothing is converted. Example: `{\"field\":\"order.currency\",\"op\":\"eq\",\"value\":\"USD\"}` |\n| `order.shipping_paid` | money | `eq` `neq` `gt` `gte` `lt` `lte` `between` `exists` `not_exists` | What the customer paid for shipping at checkout, in dollars, as sent in `order.shipping_paid`. Missing when it isn't sent; `\"0.00\"` is free shipping. Example: `{\"field\":\"order.shipping_paid\",\"op\":\"gt\",\"value\":\"0.00\"}` |\n| `order.tags` | tags | `contains` `not_contains` `in` `not_in` `exists` `not_exists` | The tags you send on the order, compared ignoring case. Example: `{\"field\":\"order.tags\",\"op\":\"contains\",\"value\":\"fragile\"}` |\n| `order.shipping_method` | text | `eq` `neq` `in` `not_in` `contains` `not_contains` `starts_with` `exists` `not_exists` | The shipping method the customer chose at checkout, e.g. \"Expedited\". Example: `{\"field\":\"order.shipping_method\",\"op\":\"contains\",\"value\":\"expedited\"}` |\n| `order.item_count` | count | `eq` `neq` `gt` `gte` `lt` `lte` `between` `exists` `not_exists` | The sum of the items' quantities. Missing when you send no items. Example: `{\"field\":\"order.item_count\",\"op\":\"gt\",\"value\":5}` |\n| `order.skus` | tags | `contains` `not_contains` `in` `not_in` `exists` `not_exists` | The SKUs of the order's items, compared ignoring case. Example: `{\"field\":\"order.skus\",\"op\":\"in\",\"value\":[\"BATTERY-LI-01\",\"BATTERY-LI-02\"]}` |\n| `reference` | text | `eq` `neq` `in` `not_in` `contains` `not_contains` `starts_with` `exists` `not_exists` | Your order reference, as sent in `reference`. Example: `{\"field\":\"reference\",\"op\":\"starts_with\",\"value\":\"WHOLESALE-\"}` |\n| `source` | enum | `eq` `neq` `in` `not_in` | Where the request came from: `api` (an API key), `admin` (someone using the admin page) or `batch` (an order in a batch). Example: `{\"field\":\"source\",\"op\":\"eq\",\"value\":\"batch\"}` |\n| `ship.day_of_week` | enum | `eq` `neq` `in` `not_in` | The weekday when the request is made, in UTC: mon, tue, wed, thu, fri, sat or sun. Example: `{\"field\":\"ship.day_of_week\",\"op\":\"in\",\"value\":[\"thu\",\"fri\"]}` |\n| `ship.date` | date | `eq` `neq` `gt` `gte` `lt` `lte` `between` | Today's date in UTC (YYYY-MM-DD), for cutoffs and holidays. Example: `{\"field\":\"ship.date\",\"op\":\"between\",\"value\":[\"2026-12-20\",\"2026-12-26\"]}` |\n\n| Operator | Takes | Meaning |\n| --- | --- | --- |\n| `eq` | a value | Equal to the value. Text is compared ignoring case. |\n| `neq` | a value | Anything but the value. A missing value counts as not equal. |\n| `in` | a list | Equal to at least one value in the list. On tags and SKUs: at least one of them is in the list. |\n| `not_in` | a list | Equal to none of the values in the list. On tags and SKUs: none of them is in the list. |\n| `gt` | a value | Greater than the value. |\n| `gte` | a value | Greater than or equal to the value. |\n| `lt` | a value | Less than the value. |\n| `lte` | a value | Less than or equal to the value. |\n| `between` | [min, max] | From the first value to the second, both included. For ZIP codes, a range of ZIP codes. |\n| `contains` | a value | Text: contains the value anywhere. Tags and SKUs: one of them is the value. |\n| `not_contains` | a value | The opposite of contains. |\n| `starts_with` | a value | Begins with the value, e.g. a ZIP prefix such as 967. |\n| `exists` | no value | Has a value. Takes no value itself. |\n| `not_exists` | no value | Has no value. Takes no value itself. |\n| `matches_any_zip` | a list | Matches any ZIP prefix (\"967\") or range (\"96701-96899\") in the list. |","anyOf":[{"$ref":"#/components/schemas/RuleTest"},{"type":"object","properties":{"all":{"type":"array","items":{"$ref":"#/components/schemas/RuleCondition"}}},"required":["all"]},{"type":"object","properties":{"any":{"type":"array","items":{"$ref":"#/components/schemas/RuleCondition"}}},"required":["any"]},{"type":"object","properties":{"not":{"$ref":"#/components/schemas/RuleCondition"}},"required":["not"]}]},"RuleTest":{"type":"object","properties":{"field":{"enum":["to.country","to.state","to.zip","to.city","to.residential","to.po_box","to.military","to.company","from.state","from.zip","from.address_id","parcel.weight","parcel.length","parcel.width","parcel.height","parcel.girth","parcel.longest_side","parcel.preset","parcel.packaging","order.value","order.currency","order.shipping_paid","order.tags","order.shipping_method","order.item_count","order.skus","reference","source","ship.day_of_week","ship.date"],"description":"What to look at. See the table on `RuleCondition`"},"op":{"enum":["eq","neq","in","not_in","gt","gte","lt","lte","between","contains","not_contains","starts_with","exists","not_exists","matches_any_zip"],"description":"How to compare it. Must fit the field's type"},"value":{"description":"Depends on the operator: none for `exists` / `not_exists`, a list for `in`, `not_in` and `matches_any_zip`, `[min, max]` for `between`, one value otherwise. Money is a dollar string like `\"100.00\"`"},"unit":{"enum":["oz","lb","g","kg","in","cm"],"description":"Weight fields take `oz` (default), `lb`, `g` or `kg`; size fields take `in` (default) or `cm`"}},"required":["field","op"]},"RuleStats":{"type":"object","properties":{"matched":{"type":"integer","description":"Recent shipments the rule matched"},"window":{"type":"integer","description":"How many recent shipments (up to 200) were looked at"},"last_matched_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"required":["matched","window","last_matched_at"]},"RuleWarning":{"type":"object","properties":{"severity":{"enum":["warning","info"]},"code":{"enum":["overlap","carrier_not_configured","service_not_offered","preset_missing","address_missing","contradiction","unreachable","needs_order_value","needs_shipping_paid"]},"rule_ids":{"type":"array","items":{"type":"string"}},"message":{"type":"string"}},"required":["severity","code","rule_ids","message"]},"Rule":{"type":"object","properties":{"id":{"type":"string","examples":["rule_019a1b2c3d4e5f60"]},"object":{"const":"Rule"},"name":{"type":"string"},"description":{"type":"string"},"enabled":{"type":"boolean"},"position":{"type":"integer","description":"1 is evaluated first"},"when":{"$ref":"#/components/schemas/RuleCondition"},"then":{"type":"array","items":{"$ref":"#/components/schemas/RuleAction"}},"stop_processing":{"type":"boolean","description":"Stop evaluating later rules when this one matches"},"summary":{"type":"string","description":"The rule in plain English","examples":["When destination state is any of HI or AK: exclude FedEx Ground."]},"stats":{"$ref":"#/components/schemas/RuleStats","description":"Only with `?include=stats` on the list"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","object","name","description","enabled","position","when","then","stop_processing","summary","created_at","updated_at"],"examples":[{"id":"rule_019a1b2c3d4e5f60","object":"Rule","name":"No Ground to Hawaii and Alaska","description":"Ground takes over a week there.","enabled":true,"position":1,"when":{"all":[{"field":"to.state","op":"in","value":["HI","AK"]}]},"then":[{"type":"exclude_services","services":["FEDEX_GROUND"]}],"stop_processing":false,"summary":"When destination state is any of HI or AK: exclude FedEx Ground.","created_at":"2026-10-13T12:00:00.000Z","updated_at":"2026-10-13T12:00:00.000Z"}]},"RuleList":{"type":"object","properties":{"object":{"const":"RuleList"},"rules":{"type":"array","items":{"$ref":"#/components/schemas/Rule"},"description":"In evaluation order"},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/RuleWarning"},"description":"Overlaps and mistakes across the rule set, e.g. two rules setting the signature, or `only_carriers` naming a carrier with no account"},"limit":{"type":"integer","examples":[50],"description":"The most rules an organization can have in each mode"}},"required":["object","rules","warnings","limit"]},"RuleEffect":{"type":"object","properties":{"action":{"type":"string","examples":["exclude_services"]},"summary":{"type":"string","examples":["exclude FedEx Ground"]},"status":{"enum":["applied","overridden","kept","skipped","relaxed"],"description":"`applied`; `overridden` (a later rule set the same thing); `kept` (what the request sent won); `skipped` (see `reason`); `relaxed` (a `max_price` with `if_none_left: \"relax\"` would have left no rate, so it removed none)"},"reason":{"type":"string"},"rates_removed":{"type":"integer","description":"For limiting actions: how many rates it removed"}},"required":["action","summary","status"]},"AppliedRule":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"effects":{"type":"array","items":{"$ref":"#/components/schemas/RuleEffect"}}},"required":["id","name","effects"]},"RemovedBy":{"type":"object","properties":{"rule_id":{"type":"string"},"rule_name":{"type":"string"},"reason":{"type":"string","examples":["FedEx Ground is excluded"]}},"required":["rule_id","rule_name","reason"]},"ExcludedRate":{"type":"object","properties":{"carrier":{"type":"string","examples":["FedEx"]},"carrier_account_id":{"type":"string"},"service":{"type":["string","null"],"description":"`null` when a whole carrier was excluded: it was never quoted"},"service_name":{"type":["string","null"]},"rate":{"anyOf":[{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]},{"type":"null"}],"description":"What it would have cost"},"removed_by":{"type":"array","items":{"$ref":"#/components/schemas/RemovedBy"}}},"required":["carrier","carrier_account_id","service","service_name","rate","removed_by"]},"RecommendedRate":{"type":"object","properties":{"id":{"type":"string","description":"The rate's ID, on shipments"},"carrier":{"type":"string"},"carrier_account_id":{"type":"string"},"service":{"type":"string"}},"required":["carrier","carrier_account_id","service"]},"Order":{"type":"object","properties":{"value":{"anyOf":[{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]},{"type":"null"}]},"currency":{"type":["string","null"]},"tags":{"type":"array","items":{"type":"string"}},"shipping_method":{"type":["string","null"]},"shipping_paid":{"anyOf":[{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]},{"type":"null"}],"description":"What the customer paid for shipping"},"items":{"type":"array","items":{"type":"object","properties":{"sku":{"type":"string"},"quantity":{"type":"integer"},"value":{"anyOf":[{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]},{"type":"null"}]}},"required":["sku","quantity","value"]}}},"required":["value","currency","tags","shipping_method","shipping_paid","items"]},"RuleTrace":{"type":"object","properties":{"type":{"enum":["all","any","not","condition"]},"result":{"type":"boolean"},"text":{"type":"string","description":"A test in plain English, e.g. `package weight is more than 20 lb`"},"field":{"type":"string"},"op":{"type":"string"},"value":{"description":"The value the rule compares against"},"actual":{"description":"What the request had for the field (weights in oz, money in dollars); null when it had nothing"},"children":{"type":"array","items":{"$ref":"#/components/schemas/RuleTrace"}}},"required":["type","result"]},"RuleTestResult":{"type":"object","properties":{"object":{"const":"RuleTest"},"rules":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"enabled":{"type":"boolean"},"evaluated":{"type":"boolean","description":"`false` for rules that weren't looked at: disabled, or after a `stop_processing` rule matched"},"matched":{"type":"boolean"},"trace":{"anyOf":[{"$ref":"#/components/schemas/RuleTrace"},{"type":"null"}],"description":"Every test and whether it held, with what the request had"}},"required":["id","name","enabled","evaluated","matched","trace"]}},"applied_rules":{"type":"array","items":{"$ref":"#/components/schemas/AppliedRule"}},"effective":{"type":"object","properties":{"options":{"$ref":"#/components/schemas/ShipmentOptions"},"protection":{"anyOf":[{"type":"object","properties":{"value":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]}},"required":["value"]},{"type":"null"}]},"parcel":{"description":"The parcel as it would be quoted: a preset name, or the parcel sent"},"from_address":{"description":"An `{ id }` when a rule chose the origin; null otherwise"},"tags":{"type":"array","items":{"type":"string"}},"notes":{"type":"array","items":{"type":"string"}}},"required":["options","protection","parcel","from_address","tags","notes"]},"blocked":{"anyOf":[{"type":"object","properties":{"rule_id":{"type":"string"},"rule_name":{"type":"string"},"message":{"type":"string"}},"required":["rule_id","rule_name","message"]},{"type":"null"}]},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/RuleWarning"}},"quote":{"anyOf":[{"$ref":"#/components/schemas/RateQuote"},{"type":"null"}],"description":"With `quote: true`"},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},{"type":"null"}],"description":"With `quote: true`: `RULES.NO_RATE` when the rules left nothing"}},"required":["object","rules","applied_rules","effective","blocked","warnings","quote","error"]},"RuleDraft":{"type":"object","properties":{"object":{"const":"RuleDraft"},"rules":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"enabled":{"type":"boolean"},"when":{"$ref":"#/components/schemas/RuleCondition"},"then":{"type":"array","items":{"$ref":"#/components/schemas/RuleAction"}},"stop_processing":{"type":"boolean"},"summary":{"type":"string"}},"required":["name","description","enabled","when","then","stop_processing","summary"]},"description":"Drafts without IDs. Nothing is saved"},"summary":{"type":"string"},"assumptions":{"type":"array","items":{"type":"string"},"description":"Choices made where the text was loose"},"questions":{"type":"array","items":{"type":"string"},"description":"Real ambiguity to resolve before relying on the draft"},"unsupported":{"type":"array","items":{"type":"string"},"description":"Parts of the request the available fields and actions can't express. Listed, never dropped silently"},"existing_rule_id":{"type":["string","null"]},"model":{"type":"string"}},"required":["object","rules","summary","assumptions","questions","unsupported","existing_rule_id","model"]},"PrintLocation":{"type":"object","properties":{"object":{"const":"PrintLocation"},"id":{"type":"string","examples":["ploc_01a1…"]},"name":{"type":"string"},"is_default":{"type":"boolean"},"failover":{"type":"boolean","description":"Jobs move to another healthy printer with the same role here when theirs can't print. On by default"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["object","id","name","is_default","failover","created_at","updated_at"]},"PrinterHealth":{"type":"object","properties":{"state":{"enum":["ready","printing","paused","offline","paper_out","paper_jam","cover_open","stuck","error"],"description":"`ready` and `printing` can print. `paused`: the queue on the computer is stopped. `stuck`: a job has sat in the computer's print queue for minutes while CUPS reports nothing wrong. `offline` also while the station is"},"label":{"type":"string","examples":["Out of paper"]},"reasons":{"type":"array","items":{"type":"string"},"description":"CUPS `printer-state-reasons` keywords, e.g. `media-empty-error`"},"warnings":{"type":"array","items":{"enum":["paper_low","toner_low","toner_out","ink_low","ink_out","marker_supply_low","marker_supply_out","ribbon_out"]},"description":"Conditions that don't stop printing, like low toner"},"message":{"type":["string","null"],"description":"What the printer or CUPS says, e.g. `Printer is out of paper.`"},"since":{"type":["string","null"],"format":"date-time","description":"When the printer entered this state"}},"required":["state","label","reasons","warnings","message","since"]},"PrintAlertSettings":{"type":"object","properties":{"enabled":{"type":"boolean"},"notify_admins":{"type":"boolean","description":"Email the organization's owners and admins"},"recipients":{"type":"array","items":{"type":"string","format":"email"},"description":"Other addresses"},"problem_minutes":{"type":"integer","description":"How long a printer problem lasts before the email"},"business_hours":{"anyOf":[{"type":"object","properties":{"timezone":{"type":"string"},"days":{"type":"array","items":{"type":"integer","minimum":0,"maximum":6}},"start":{"type":"string"},"end":{"type":"string"}},"required":["timezone","days","start","end"]},{"type":"null"}],"description":"Offline stations are emailed only in these hours; `null` is any time"}},"required":["enabled","notify_admins","recipients","problem_minutes","business_hours"]},"PrintSettings":{"type":"object","properties":{"object":{"const":"PrintSettings"},"alerts":{"$ref":"#/components/schemas/PrintAlertSettings"}},"required":["object","alerts"]},"Printer":{"type":"object","properties":{"object":{"const":"Printer"},"id":{"type":"string","examples":["prn_01a1…"]},"station_id":{"type":"string"},"location_id":{"type":"string"},"system_name":{"type":"string","description":"The CUPS queue name on the station","examples":["Rollo_Printer"]},"name":{"type":"string"},"make_model":{"type":["string","null"]},"connection":{"enum":["cups","network"],"description":"`cups`: a printer queue the station reports. `network`: added by hand; the station connects to `host`:`port` itself"},"host":{"type":["string","null"],"description":"Network printers: IP address or host name"},"port":{"type":["integer","null"]},"protocol":{"anyOf":[{"enum":["raw9100","ipp"]},{"type":"null"}],"description":"`raw9100` (JetDirect/AppSocket) or `ipp`"},"path":{"type":["string","null"],"description":"IPP resource path, e.g. `/ipp/print`"},"languages":{"type":"array","items":{"enum":["pdf","zpl"]},"description":"What it takes. ZPL jobs go only to printers with `zpl`; PDFs and images only to printers with `pdf`"},"reported_languages":{"anyOf":[{"type":"array","items":{"enum":["pdf","zpl"]}},{"type":"null"}],"description":"What the station detected (Zebra and ZPL drivers, raw queues); `null` for network printers"},"status":{"enum":["idle","printing","offline","error"],"description":"`offline` whenever the station is"},"status_detail":{"type":["string","null"],"description":"What CUPS says, e.g. `Paused` or `media-empty`"},"media_sizes":{"type":"array","items":{"type":"string"},"description":"Media the driver offers, e.g. `w288h432`"},"roles":{"type":"array","items":{"enum":["label","slip","letter"]}},"default_for":{"type":"array","items":{"enum":["label","slip","letter"]},"description":"Roles it is the location's default printer for"},"is_system_default":{"type":"boolean"},"last_reported_at":{"type":["string","null"],"format":"date-time"},"health":{"anyOf":[{"$ref":"#/components/schemas/PrinterHealth"},{"type":"null"}],"description":"From agent 0.3.0; `null` for older agents while the station is online"},"created_at":{"type":"string","format":"date-time"}},"required":["object","id","station_id","location_id","system_name","name","make_model","connection","host","port","protocol","path","languages","reported_languages","status","status_detail","media_sizes","roles","default_for","is_system_default","last_reported_at","health","created_at"]},"PrintStation":{"type":"object","properties":{"object":{"const":"PrintStation"},"id":{"type":"string","examples":["pst_01a1…"]},"name":{"type":"string"},"location_id":{"type":"string"},"status":{"enum":["online","offline","paused","revoked"],"description":"`online` when the agent was heard from in the last 90 seconds"},"paused":{"type":"boolean"},"platform":{"type":["string","null"]},"arch":{"type":["string","null"]},"hostname":{"type":["string","null"]},"agent_version":{"type":["string","null"],"description":"What the agent last reported"},"agent_update":{"$ref":"#/components/schemas/PrintAgentUpdate"},"auto_update":{"type":"boolean","description":"The agent installs new releases by itself, between jobs"},"update_requested_at":{"type":["string","null"],"format":"date-time","description":"Someone asked for an update with `POST /v1/print/stations/{id}/update`; cleared once the agent runs a newer version"},"stay_awake":{"anyOf":[{"type":"object","properties":{"idle":{"type":"boolean","description":"The agent keeps the Mac from sleeping when idle"},"lid":{"type":["boolean","null"],"description":"`pmset disablesleep` is on, so it stays awake with the lid closed too"}},"required":["idle","lid"]},{"type":"null"}],"description":"macOS stations only; `null` elsewhere and for agents before 0.2.0"},"capabilities":{"type":"array","items":{"enum":["zpl","network"]},"description":"What the agent can do beyond PDFs on printer queues: print ZPL raw, and reach network printers"},"discovered_printers":{"type":"array","items":{"$ref":"#/components/schemas/DiscoveredPrinter"},"description":"Printers the agent found with Bonjour that aren't added yet"},"discovered_at":{"type":["string","null"],"format":"date-time"},"paired_at":{"type":"string","format":"date-time"},"last_seen_at":{"type":["string","null"],"format":"date-time"},"revoked_at":{"type":["string","null"],"format":"date-time"},"printers":{"type":"array","items":{"$ref":"#/components/schemas/Printer"}}},"required":["object","id","name","location_id","status","paused","platform","arch","hostname","agent_version","agent_update","auto_update","update_requested_at","stay_awake","capabilities","discovered_printers","discovered_at","paired_at","last_seen_at","revoked_at","printers"]},"DiscoveredPrinter":{"type":"object","properties":{"name":{"type":"string"},"host":{"type":"string"},"port":{"type":"integer"},"protocol":{"enum":["raw9100","ipp"]}},"required":["name","host","port","protocol"]},"PrintAgentUpdate":{"type":"object","properties":{"latest_version":{"type":["string","null"],"description":"The latest published agent release built for the station's platform"},"status":{"enum":["up_to_date","available","updating","failed","manual","unknown"],"description":"`updating`: offered to the agent, which installs it once nothing is printing. `manual`: the agent is older than 0.2.0 and can't update itself; run the install command on the station once. `unknown`: nothing published, or the station hasn't reported a version"},"error":{"type":["string","null"],"description":"Why the last update didn't take, when `status` is `failed`"}},"required":["latest_version","status","error"]},"PrintDiagnostics":{"type":"object","properties":{"object":{"const":"PrintDiagnostics"},"id":{"type":"string","examples":["pdiag_01a1…"]},"station_id":{"type":"string"},"status":{"enum":["requested","received","expired"],"description":"`requested`: waiting for the agent, which answers within a minute when online. `expired`: it didn't answer within an hour"},"reason":{"enum":["requested","crash","rollback","manual"],"description":"`requested` with `POST /v1/print/stations/{id}/diagnostics`; `crash` and `rollback` were sent by the agent unasked; `manual` by `veloship-print diagnostics --upload` on the station"},"requested_at":{"type":["string","null"],"format":"date-time"},"received_at":{"type":["string","null"],"format":"date-time"},"size_bytes":{"type":["integer","null"],"description":"Of the gzipped bundle, at most 2 MB"},"agent_version":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time","description":"When the bundle is deleted, 7 days after it was created"}},"required":["object","id","station_id","status","reason","requested_at","received_at","size_bytes","agent_version","created_at","expires_at"]},"PrintPairingCode":{"type":"object","properties":{"object":{"const":"PrintPairingCode"},"code":{"type":"string","examples":["K7QM-4XPT"],"description":"One use, valid for 15 minutes"},"location_id":{"type":"string"},"name":{"type":["string","null"]},"expires_at":{"type":"string","format":"date-time"},"install_command":{"type":"string","examples":["curl -fsSL https://ship.vprev.dev/print/install.sh | sh -s -- K7QM-4XPT"]},"pair_command":{"type":"string","description":"For an agent that is already installed"}},"required":["object","code","location_id","name","expires_at","install_command","pair_command"]},"PrintRouting":{"type":"object","properties":{"by":{"enum":["printer","kind","role"]},"role":{"anyOf":[{"enum":["label","slip","letter"]},{"type":"null"}]},"fallback":{"type":"boolean","description":"A slip went to the label printer because the location has no slip printer"}},"required":["by","role","fallback"]},"PrintJob":{"type":"object","properties":{"object":{"const":"PrintJob"},"id":{"type":"string","examples":["pjob_01a1…"]},"mode":{"enum":["live","test"],"description":"The mode of the key that created it. Printers are shared by both modes"},"status":{"enum":["queued","sent","printing","done","failed","cancelled","expired"]},"kind":{"enum":["label","slip","packing_list","invoice","document"]},"tags":{"type":"array","items":{"type":"string"}},"title":{"type":"string"},"source":{"enum":["upload","shipment_label","shipment_labels","batch_labels","test_page","reprint"]},"source_ids":{"type":"array","items":{"type":"string"}},"reprint_of":{"type":["string","null"]},"printer_id":{"type":"string"},"station_id":{"type":"string"},"location_id":{"type":"string"},"routing":{"$ref":"#/components/schemas/PrintRouting"},"copies":{"type":"integer"},"paper":{"enum":["4x6","letter"]},"fit":{"enum":["actual","fit"]},"priority":{"type":"integer"},"page_count":{"type":"integer"},"size_bytes":{"type":"integer"},"attempts":{"type":"integer","description":"Deliveries to the station so far"},"cups_job_id":{"type":["string","null"],"examples":["Rollo-42"]},"error":{"type":["string","null"]},"idempotency_key":{"type":["string","null"]},"file_available":{"type":"boolean","description":"`false` once the file is past retention (`PRINT_FILE_RETENTION_DAYS`, 7 by default)"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"sent_at":{"type":["string","null"],"format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"},"expires_at":{"type":"string","format":"date-time","description":"Still queued at this time, it becomes `expired`"},"rerouted_from":{"type":["string","null"],"description":"The printer it was last moved away from because that printer couldn't print"},"reroute_reason":{"type":["string","null"],"examples":["Rollo X1040 is out of paper"]},"reroute_count":{"type":"integer"},"waiting_reason":{"type":["string","null"],"description":"Why a queued job isn't printing yet","examples":["Packing Mac is offline"]}},"required":["object","id","mode","status","kind","tags","title","source","source_ids","reprint_of","printer_id","station_id","location_id","routing","copies","paper","fit","priority","page_count","size_bytes","attempts","cups_job_id","error","idempotency_key","file_available","created_at","updated_at","sent_at","finished_at","expires_at","rerouted_from","reroute_reason","reroute_count","waiting_reason"]},"AddressWarning":{"type":"object","properties":{"code":{"enum":["SUITE_MISSING","SUITE_INVALID","PO_BOX","NOT_CONFIRMED","NOT_RESOLVED"],"description":"`SUITE_MISSING`, `SUITE_INVALID`, `PO_BOX`, `NOT_CONFIRMED` (USPS can't confirm the street) or `NOT_RESOLVED`"},"message":{"type":"string","examples":["Needs a suite or apartment number"]}},"required":["code","message"]},"Address":{"type":"object","properties":{"id":{"type":"string","examples":["adr_01a131ca1cc83766d0ac435ef"]},"object":{"const":"Address"},"name":{"type":["string","null"]},"company":{"type":["string","null"]},"street1":{"type":"string"},"street2":{"type":["string","null"]},"city":{"type":"string"},"state":{"type":["string","null"]},"zip":{"type":"string"},"country":{"type":"string","examples":["US"]},"phone":{"type":["string","null"]},"email":{"type":["string","null"]},"residential":{"type":["boolean","null"],"description":"`null` until FedEx has classified the address"},"verification":{"anyOf":[{"type":"object","properties":{"success":{"type":"boolean"},"residential":{"type":["boolean","null"]},"messages":{"type":"array","items":{"type":"string"}},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/AddressWarning"},"description":"The same findings as `messages`, by code"}},"required":["success","residential","messages","warnings"]},{"type":"null"}]},"created_at":{"type":"string","format":"date-time"}},"required":["id","object","name","company","street1","street2","city","state","zip","country","phone","email","residential","verification","created_at"]},"RateDescription":{"type":"object","properties":{"summary":{"type":"string"},"arrives":{"type":"string"},"weekends":{"type":"string"},"travels":{"type":"string"},"good_for":{"type":"string"},"keep_in_mind":{"type":"string"}},"required":["summary","arrives","weekends","travels","good_for","keep_in_mind"]},"CarrierQuoteError":{"type":"object","properties":{"carrier":{"type":"string","examples":["FedEx"]},"carrier_account_id":{"type":"string"},"code":{"type":"string","examples":["CARRIER.TIMEOUT"],"description":"`CARRIER.TIMEOUT`, `CARRIER.ERROR`, `CARRIER.UNAVAILABLE`, `CARRIER.UNSUPPORTED_OPTION`, `CARRIER.UNSUPPORTED_DESTINATION` or `SHIPMENT.ONE_RATE.INELIGIBLE`"},"message":{"type":"string"}},"required":["carrier","carrier_account_id","code","message"]},"QuotedRate":{"type":"object","properties":{"carrier":{"type":"string","examples":["FedEx"],"description":"The carrier's display name"},"carrier_account_id":{"type":"string","examples":["ca_env_fedex"],"description":"The carrier account that quoted it"},"service":{"type":"string","examples":["FEDEX_GROUND"]},"service_name":{"type":"string","examples":["FedEx Ground"]},"rate":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"],"description":"Your account rate"},"list_rate":{"anyOf":[{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]},{"type":"null"}]},"currency":{"type":"string","examples":["USD"]},"delivery_days":{"type":["integer","null"]},"delivery_date":{"type":["string","null"]},"one_rate":{"type":"boolean"},"purchasable":{"type":"boolean","description":"`false` while the carrier hasn't enabled label creation for the account, as its latest connection test or a refused purchase showed. The rate is still a valid quote; automatic picks (`cheapest`, `fastest`, `best_value`, a rule's `pick`, a batch strategy) skip it"},"purchase_note":{"type":["string","null"],"description":"Why the rate can't be bought yet; `null` when `purchasable`"},"description":{"anyOf":[{"$ref":"#/components/schemas/RateDescription"},{"type":"null"}],"description":"Only with `?descriptive`"}},"required":["carrier","carrier_account_id","service","service_name","rate","list_rate","currency","delivery_days","delivery_date","one_rate","purchasable","purchase_note"]},"Rate":{"allOf":[{"$ref":"#/components/schemas/QuotedRate"},{"type":"object","properties":{"id":{"type":"string","examples":["rate_01a131…"]}},"required":["id"]}]},"Protection":{"type":"object","properties":{"value":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]},"fee":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]},"currency":{"const":"USD"}},"required":["value","fee","currency"]},"RateQuote":{"type":"object","properties":{"object":{"const":"RateQuote"},"rates":{"type":"array","items":{"$ref":"#/components/schemas/QuotedRate"}},"carrier_errors":{"type":"array","items":{"$ref":"#/components/schemas/CarrierQuoteError"},"description":"Carriers left out of `rates` because they were late, failed or can't price the request. Empty when every carrier answered"},"protection":{"anyOf":[{"$ref":"#/components/schemas/Protection"},{"type":"null"}],"description":"The protection fee, when `protection` was requested"},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/AddressWarning"},"description":"Problems with the destination address. They don't block buying"},"applied_rules":{"type":"array","items":{"$ref":"#/components/schemas/AppliedRule"},"description":"The shipping rules that matched and what each did. Empty when none matched or `apply_rules` was `false`"},"excluded_rates":{"type":"array","items":{"$ref":"#/components/schemas/ExcludedRate"},"description":"Rates, or whole carriers, the rules removed, and why. They aren't in `rates`"},"recommended_rate":{"anyOf":[{"$ref":"#/components/schemas/RecommendedRate"},{"type":"null"}],"description":"The rate a `pick` rule chose, when one did"},"quoted_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"}},"required":["object","rates","carrier_errors","protection","warnings","applied_rules","excluded_rates","recommended_rate","quoted_at","expires_at"]},"Shipment":{"type":"object","properties":{"id":{"type":"string","examples":["shp_01a131ca1cec532ff358a581e16a"]},"object":{"const":"Shipment"},"mode":{"enum":["live","test"]},"reference":{"type":["string","null"],"description":"Your order ID"},"status":{"enum":["created","purchasing","purchase_unknown","purchased","refunded"]},"carrier":{"type":["string","null"],"description":"The carrier the label was bought from; `null` until a rate is bought"},"carrier_account_id":{"type":["string","null"]},"from_address":{"$ref":"#/components/schemas/Address"},"to_address":{"$ref":"#/components/schemas/Address"},"parcel":{"$ref":"#/components/schemas/Parcel"},"options":{"$ref":"#/components/schemas/ShipmentOptions"},"protection":{"anyOf":[{"$ref":"#/components/schemas/Protection"},{"type":"null"}]},"rates":{"type":"array","items":{"$ref":"#/components/schemas/Rate"}},"carrier_errors":{"type":"array","items":{"$ref":"#/components/schemas/CarrierQuoteError"},"description":"Carriers left out of `rates` when it was quoted"},"rates_expire_at":{"type":"string","format":"date-time"},"selected_rate":{"anyOf":[{"$ref":"#/components/schemas/Rate"},{"type":"null"}]},"charged":{"anyOf":[{"type":"object","properties":{"amount":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]},"currency":{"type":["string","null"]}},"required":["amount","currency"]},{"type":"null"}],"description":"What FedEx says it will bill"},"charge_mismatch":{"type":"boolean","description":"`true` when FedEx charged a different amount than the quote"},"tracking_code":{"type":["string","null"]},"label_url":{"type":["string","null"]},"label_format":{"enum":["PDF","PNG","ZPLII",null]},"customs_info":{"anyOf":[{"$ref":"#/components/schemas/CustomsInfo"},{"type":"null"}],"description":"The customs declaration, as stored. `null` unless one was sent"},"forms":{"type":"array","items":{"$ref":"#/components/schemas/ShipmentForm"},"description":"Customs documents bought with the label, such as a commercial invoice. Empty for domestic shipments"},"tracker_id":{"type":["string","null"]},"tracking_status":{"enum":["unknown","pre_transit","in_transit","out_for_delivery","delivered","available_for_pickup","return_to_sender","failure",null],"description":"The tracker's latest status. Once it's past `pre_transit` the carrier has the package and the label can't be voided"},"public_tracking_url":{"type":["string","null"],"description":"Recipient-facing tracking page: status, timeline and estimated delivery, never the street address, phone or email"},"purchased_by":{"type":["string","null"]},"purchase_error":{"type":["string","null"]},"return_of":{"type":["string","null"],"description":"On a return label, the shipment it returns"},"return_shipment_id":{"type":["string","null"],"description":"The return label bought for this shipment"},"applied_rules":{"type":"array","items":{"$ref":"#/components/schemas/AppliedRule"},"description":"The shipping rules that matched when the shipment was created, and what each did"},"excluded_rates":{"type":"array","items":{"$ref":"#/components/schemas/ExcludedRate"},"description":"Rates, or whole carriers, the rules removed, and why. They aren't in `rates` and can't be bought"},"recommended_rate":{"anyOf":[{"$ref":"#/components/schemas/RecommendedRate"},{"type":"null"}],"description":"The rate a `pick` rule chose, when one did"},"tags":{"type":"array","items":{"type":"string"},"description":"Added by `add_tag` rules"},"notes":{"type":"array","items":{"type":"string"},"description":"Added by `add_note` rules"},"order":{"anyOf":[{"$ref":"#/components/schemas/Order"},{"type":"null"}],"description":"What was ordered, as sent"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","object","mode","reference","status","carrier","carrier_account_id","from_address","to_address","parcel","options","protection","rates","carrier_errors","rates_expire_at","selected_rate","charged","charge_mismatch","tracking_code","label_url","label_format","customs_info","forms","tracker_id","tracking_status","public_tracking_url","purchased_by","purchase_error","return_of","return_shipment_id","applied_rules","excluded_rates","recommended_rate","tags","notes","order","created_at","updated_at"]},"CustomsItem":{"type":"object","properties":{"description":{"type":"string"},"quantity":{"type":"integer"},"value":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"],"description":"The whole line's value in USD"},"weight":{"type":"number","description":"The whole line's weight in ounces"},"origin_country":{"type":"string","examples":["US"]},"hs_tariff_number":{"type":["string","null"],"examples":["610910"],"description":"Digits only"},"code":{"type":["string","null"],"description":"Your SKU"}},"required":["description","quantity","value","weight","origin_country","hs_tariff_number","code"]},"CustomsInfo":{"type":"object","properties":{"contents_type":{"enum":["merchandise","gift","documents","returned_goods","sample","other"]},"contents_explanation":{"type":["string","null"]},"customs_certify":{"type":"boolean"},"customs_signer":{"type":["string","null"]},"eel_pfc":{"type":["string","null"],"examples":["NOEEI 30.37(a)"]},"restriction_type":{"enum":["none","other","quarantine","sanitary_phytosanitary_inspection"]},"restriction_comments":{"type":["string","null"]},"non_delivery_option":{"enum":["return","abandon"]},"customs_items":{"type":"array","items":{"$ref":"#/components/schemas/CustomsItem"}}},"required":["contents_type","contents_explanation","customs_certify","customs_signer","eel_pfc","restriction_type","restriction_comments","non_delivery_option","customs_items"]},"ShipmentForm":{"type":"object","properties":{"object":{"const":"Form"},"form_type":{"enum":["commercial_invoice","cn22","cn23"]},"form_url":{"type":"string","description":"Authenticated, like `label_url`"},"submitted_electronically":{"type":"boolean","description":"The carrier already sent it to customs electronically (FedEx ETD); a paper copy is optional"}},"required":["object","form_type","form_url","submitted_electronically"]},"CarrierInternational":{"type":"object","properties":{"origins":{"type":"array","items":{"type":"string"},"description":"Countries labels can leave from"},"destinations":{"type":["array","null"],"items":{"type":"string"},"description":"`null` means any country not in `excluded_destinations`"},"excluded_destinations":{"type":"array","items":{"type":"string"},"description":"Embargoed or suspended destinations"},"duties_payers":{"type":"array","items":{"enum":["sender","recipient"]}},"forms":{"type":"array","items":{"enum":["commercial_invoice","cn22","cn23"]},"description":"Customs documents returned with the label"}},"required":["origins","destinations","excluded_destinations","duties_payers","forms"]},"RateChoice":{"type":"object","properties":{"carrier":{"type":"string"},"carrier_account_id":{"type":"string"},"service":{"type":"string"},"service_name":{"type":"string"},"rate":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]},"currency":{"type":"string"},"delivery_date":{"type":["string","null"]},"delivery_days":{"type":["integer","null"]},"one_rate":{"type":"boolean"},"packaging":{"type":"string","description":"What to pack it in, e.g. `FEDEX_MEDIUM_BOX`; `YOUR_PACKAGING` means your own box"}},"required":["carrier","carrier_account_id","service","service_name","rate","currency","delivery_date","delivery_days","one_rate","packaging"]},"RateComparisonItem":{"type":"object","properties":{"index":{"type":"integer"},"reference":{"type":["string","null"]},"status":{"enum":["ok","error"]},"chosen":{"anyOf":[{"$ref":"#/components/schemas/RateChoice"},{"type":"null"}],"description":"What a batch with the same body would buy"},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/AddressWarning"},"description":"Problems with the destination address. They don't block buying"},"applied_rules":{"type":"array","items":{"$ref":"#/components/schemas/AppliedRule"},"description":"The shipping rules that matched this order"},"excluded_rates":{"type":"array","items":{"$ref":"#/components/schemas/ExcludedRate"},"description":"Rates, or whole carriers, the rules removed, and why"},"alternative":{"anyOf":[{"$ref":"#/components/schemas/RateChoice"},{"type":"null"}],"description":"The best option the other way (One Rate or your own packaging)"},"difference":{"type":["string","null"],"description":"`alternative.rate - chosen.rate`. Negative when `fastest` pays more to arrive sooner"},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},{"type":"null"}]}},"required":["index","reference","status","chosen","warnings","applied_rules","excluded_rates","alternative","difference","error"]},"RateComparison":{"type":"object","properties":{"object":{"const":"RateComparison"},"items":{"type":"array","items":{"$ref":"#/components/schemas/RateComparisonItem"}},"summary":{"type":"object","properties":{"orders":{"type":"integer"},"quoted":{"type":"integer"},"failed":{"type":"integer"},"one_rate_orders":{"type":"integer"},"total":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"],"description":"What buying every quoted order as chosen would cost"},"difference":{"type":"string","description":"Sum of the items' `difference`"},"currency":{"const":"USD"}},"required":["orders","quoted","failed","one_rate_orders","total","difference","currency"]},"quoted_at":{"type":"string","format":"date-time"}},"required":["object","items","summary","quoted_at"]},"ShipmentList":{"type":"object","properties":{"shipments":{"type":"array","items":{"$ref":"#/components/schemas/Shipment"}},"has_more":{"type":"boolean"}},"required":["shipments","has_more"]},"BatchItem":{"type":"object","properties":{"index":{"type":"integer"},"reference":{"type":["string","null"]},"recipient":{"type":["string","null"],"description":"The recipient's name or company, when the order gave the address inline"},"destination":{"type":["string","null"],"description":"\"City, ST\", when the order gave the address inline"},"status":{"enum":["pending","purchased","failed"]},"shipment_id":{"type":["string","null"]},"tracking_code":{"type":["string","null"]},"carrier":{"type":["string","null"]},"carrier_account_id":{"type":["string","null"]},"service":{"type":["string","null"]},"rate":{"anyOf":[{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]},{"type":"null"}]},"packaging":{"type":["string","null"],"description":"What to pack it in, e.g. `FEDEX_MEDIUM_BOX`; `YOUR_PACKAGING` means your own box"},"one_rate":{"type":["boolean","null"]},"compared_rate":{"anyOf":[{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]},{"type":"null"}],"description":"With `one_rate: \"compare\"`, the best price of the option that wasn't chosen"},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/AddressWarning"},"description":"Problems with the destination address. They don't block the purchase"},"applied_rules":{"type":"array","items":{"$ref":"#/components/schemas/AppliedRule"},"description":"The shipping rules that matched this order"},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},{"type":"null"}]},"request":{"type":"object","description":"The order as it was sent (an item of `CreateBatch`'s `shipments`), with the batch's defaults filled in"}},"required":["index","reference","recipient","destination","status","shipment_id","tracking_code","carrier","carrier_account_id","service","rate","packaging","one_rate","compared_rate","warnings","applied_rules","error","request"]},"Batch":{"type":"object","properties":{"id":{"type":"string","examples":["bat_01a131d632a4fb48d882ea458a8c"]},"object":{"const":"Batch"},"status":{"enum":["processing","completed","completed_with_errors"]},"label_format":{"enum":["PDF","ZPLII"]},"total":{"type":"integer"},"purchased":{"type":"integer"},"failed":{"type":"integer"},"pending":{"type":"integer"},"spend":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"],"description":"What the purchased labels cost: the carrier's charge, or the quote when none is recorded"},"labels_url":{"type":"string","description":"Every purchased label in one file"},"items":{"type":"array","items":{"$ref":"#/components/schemas/BatchItem"}},"created_at":{"type":"string","format":"date-time"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"required":["id","object","status","label_format","total","purchased","failed","pending","spend","labels_url","items","created_at","completed_at"]},"BatchSummary":{"type":"object","properties":{"id":{"type":"string","examples":["bat_01a131d632a4fb48d882ea458a8c"]},"object":{"const":"Batch"},"status":{"enum":["processing","completed","completed_with_errors"]},"label_format":{"enum":["PDF","ZPLII"]},"total":{"type":"integer"},"purchased":{"type":"integer"},"failed":{"type":"integer"},"pending":{"type":"integer"},"spend":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"],"description":"What the purchased labels cost"},"labels_url":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"required":["id","object","status","label_format","total","purchased","failed","pending","spend","labels_url","created_at","completed_at"]},"BatchList":{"type":"object","properties":{"batches":{"type":"array","items":{"$ref":"#/components/schemas/BatchSummary"}},"has_more":{"type":"boolean"}},"required":["batches","has_more"]},"ReportTotals":{"type":"object","properties":{"labels":{"type":"integer","description":"Labels bought and not voided"},"spend":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]}},"required":["labels","spend"]},"ReportSummary":{"type":"object","properties":{"object":{"const":"ReportSummary"},"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"},"currency":{"const":"USD"},"labels":{"type":"integer"},"spend":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"],"description":"What FedEx charged, or the quote when no charge is recorded"},"by_service":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/ReportTotals"},{"type":"object","properties":{"service":{"type":"string"},"service_name":{"type":"string"}},"required":["service","service_name"]}]},"description":"Biggest spend first"},"by_day":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/ReportTotals"},{"type":"object","properties":{"date":{"type":"string","format":"date"}},"required":["date"]}]},"description":"Oldest first"},"one_rate":{"type":"object","properties":{"orders":{"type":"integer","description":"Batch orders bought in FedEx packaging after a comparison"},"savings":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"],"description":"The price in their own packaging minus the One Rate price, summed"}},"required":["orders","savings"]},"protection":{"type":"object","properties":{"protected_shipments":{"type":"integer"},"fees_collected":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]},"claims_paid":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]},"net":{"type":"string","examples":["536.53","-13.93"]}},"required":["protected_shipments","fees_collected","claims_paid","net"]},"claims_open":{"type":"integer"},"exceptions":{"type":"object","properties":{"purchase_unknown":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"reference":{"type":["string","null"]},"recipient":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"}},"required":["id","reference","recipient","created_at"]}},"failed_batch_items":{"type":"array","items":{"type":"object","properties":{"batch_id":{"type":"string"},"index":{"type":"integer"},"reference":{"type":["string","null"]},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"at":{"type":"string","format":"date-time"}},"required":["batch_id","index","reference","error","at"]}},"failed_webhook_deliveries":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"webhook_id":{"type":"string"},"last_error":{"type":["string","null"]},"at":{"type":"string","format":"date-time"}},"required":["id","webhook_id","last_error","at"]}}},"required":["purchase_unknown","failed_batch_items","failed_webhook_deliveries"],"description":"What needs action, whatever the range. Failed items and deliveries from the last 7 days; at most 20 of each"}},"required":["object","from","to","currency","labels","spend","by_service","by_day","one_rate","protection","claims_open","exceptions"]},"Draft":{"type":"object","properties":{"id":{"type":"string"},"object":{"const":"Draft"},"name":{"type":"string","description":"The recipient's name, company or street"},"payload":{"type":"object","description":"Whatever the client saved; the admin stores its Ship form"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","object","name","payload","created_at","updated_at"]},"DraftList":{"type":"object","properties":{"drafts":{"type":"array","items":{"$ref":"#/components/schemas/Draft"}}},"required":["drafts"]},"Claim":{"type":"object","properties":{"id":{"type":"string","examples":["clm_01a131ca1d1593fef46403dc07f8"]},"object":{"const":"Claim"},"shipment_id":{"type":"string"},"reference":{"type":["string","null"]},"tracking_code":{"type":["string","null"]},"recipient":{"type":["string","null"]},"reason":{"enum":["lost","stolen","damaged","other"]},"description":{"type":["string","null"]},"status":{"enum":["open","approved","denied"]},"resolution":{"enum":["refund","reship",null]},"amount":{"anyOf":[{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]},{"type":"null"}],"description":"What the claim cost you"},"notes":{"type":["string","null"]},"source":{"enum":["staff","customer"],"description":"`customer` when the recipient filed it from the tracking page"},"contact_email":{"type":["string","null"],"description":"Where to reach the customer; set on customer claims"},"photos":{"type":"array","description":"Fetch each with `GET /v1/claims/{id}/photos/{photo_id}`","items":{"type":"object","properties":{"id":{"type":"string"},"content_type":{"enum":["image/jpeg","image/png","image/webp","image/heic"]},"size":{"type":"integer","description":"Bytes"}},"required":["id","content_type","size"]}},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","object","shipment_id","reference","tracking_code","recipient","reason","description","status","resolution","amount","notes","source","contact_email","photos","created_at","updated_at"]},"ClaimList":{"type":"object","properties":{"claims":{"type":"array","items":{"$ref":"#/components/schemas/Claim"}},"has_more":{"type":"boolean"}},"required":["claims","has_more"]},"ProtectionSummary":{"type":"object","properties":{"object":{"const":"ProtectionSummary"},"protected_shipments":{"type":"integer"},"fees_collected":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]},"claims_open":{"type":"integer"},"claims_approved":{"type":"integer"},"claims_denied":{"type":"integer"},"claims_paid":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]},"net":{"type":"string","examples":["536.53","-13.93"]},"currency":{"const":"USD"}},"required":["object","protected_shipments","fees_collected","claims_open","claims_approved","claims_denied","claims_paid","net","currency"]},"ProtectionSettings":{"type":"object","properties":{"enabled":{"type":"boolean"},"percent":{"type":"number","description":"Percent of the order value"},"minimum":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]},"max_value":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]},"default_on":{"type":"boolean","description":"Whether the admin's protection switch starts on"}},"required":["enabled","percent","minimum","max_value","default_on"]},"Settings":{"type":"object","properties":{"object":{"const":"Settings"},"default_from_address":{"anyOf":[{"$ref":"#/components/schemas/Address"},{"type":"null"}]},"parcel_presets":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ParcelPreset"}},"protection":{"$ref":"#/components/schemas/ProtectionSettings"},"emails":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Email recipients when the package ships, is out for delivery and is delivered"},"configured":{"type":"boolean","description":"Read-only: whether the server has a sender address and a way to send (Resend or Cloudflare Email Service). Nothing is sent while false"}},"required":["enabled","configured"]},"branding":{"$ref":"#/components/schemas/BrandingSettings"}},"required":["object","default_from_address","parcel_presets","protection","emails","branding"]},"AccentShade":{"type":"object","properties":{"accent":{"type":"string","examples":["#b2401f"]},"ink":{"type":"string","description":"Text colour on the accent","examples":["#ffffff"]},"contrast":{"type":"number","description":"The accent's contrast against the theme's page and card backgrounds (the lower one); at least 4.5"}},"required":["accent","ink","contrast"]},"BrandingSettings":{"type":"object","properties":{"store_name":{"type":["string","null"],"description":"Shown in the tracking page header. `null` uses the from address's company or name"},"accent_color":{"type":["string","null"],"description":"`#rrggbb` as given"},"store_url":{"type":["string","null"],"description":"https only; shown as \"Visit store\""},"support_email":{"type":["string","null"],"description":"Shown as \"Contact the store\" (a mailto link)"},"theme":{"enum":["light","device"],"description":"`light` (default) opens the page light; `device` follows the visitor's system setting. Visitors can always toggle"},"logo":{"anyOf":[{"type":"object","properties":{"url":{"type":"string","description":"Fetch with your API key"},"content_type":{"enum":["image/png","image/jpeg","image/webp","image/svg+xml"]},"size":{"type":"integer"},"updated_at":{"type":"string","format":"date-time"}},"required":["url","content_type","size","updated_at"]},{"type":"null"}]},"palette":{"anyOf":[{"type":"object","properties":{"light":{"$ref":"#/components/schemas/AccentShade"},"dark":{"$ref":"#/components/schemas/AccentShade"},"adjusted":{"type":"boolean","description":"Whether either theme changed the colour to keep 4.5:1 contrast"}},"required":["light","dark","adjusted"]},{"type":"null"}],"description":"The accent as each theme draws it; `null` without an accent colour"}},"required":["store_name","accent_color","store_url","support_email","theme","logo","palette"]},"TrackingEvent":{"type":"object","properties":{"datetime":{"type":"string","format":"date-time"},"status":{"enum":["unknown","pre_transit","in_transit","out_for_delivery","delivered","available_for_pickup","return_to_sender","failure"]},"message":{"type":"string"},"city":{"type":["string","null"]},"state":{"type":["string","null"]},"zip":{"type":["string","null"]},"country":{"type":["string","null"]}},"required":["datetime","status","message","city","state","zip","country"]},"Tracker":{"type":"object","properties":{"id":{"type":"string","examples":["trk_01a131…"]},"object":{"const":"Tracker"},"carrier":{"type":"string","examples":["FedEx"]},"carrier_account_id":{"type":"string"},"tracking_code":{"type":"string"},"shipment_id":{"type":["string","null"]},"status":{"enum":["unknown","pre_transit","in_transit","out_for_delivery","delivered","available_for_pickup","return_to_sender","failure"]},"status_detail":{"type":["string","null"]},"est_delivery_date":{"type":["string","null"]},"tracking_details":{"type":"array","items":{"$ref":"#/components/schemas/TrackingEvent"}},"last_checked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","object","carrier","carrier_account_id","tracking_code","shipment_id","status","status_detail","est_delivery_date","tracking_details","last_checked_at","created_at","updated_at"]},"TrackerList":{"type":"object","properties":{"trackers":{"type":"array","items":{"$ref":"#/components/schemas/Tracker"}},"has_more":{"type":"boolean"}},"required":["trackers","has_more"]},"WaitlistEntry":{"type":"object","properties":{"object":{"const":"WaitlistEntry"},"id":{"type":"string"},"email":{"type":"string"},"store_url":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"}},"required":["object","id","email","store_url","created_at"]},"PublicTracking":{"type":"object","properties":{"object":{"const":"PublicTracking"},"status":{"enum":["unknown","pre_transit","in_transit","out_for_delivery","delivered","available_for_pickup","return_to_sender","failure"]},"status_label":{"type":"string","examples":["Out for delivery"]},"est_delivery_date":{"type":["string","null"]},"carrier":{"type":"string","examples":["FedEx"]},"tracking_code":{"type":["string","null"]},"shipped_by":{"type":["string","null"],"description":"The store: branding's `store_name`, else the from address's company or name"},"destination":{"type":"object","properties":{"city":{"type":"string"},"state":{"type":["string","null"]},"country":{"type":"string"}},"required":["city","state","country"]},"events":{"type":"array","description":"Newest first","items":{"type":"object","properties":{"datetime":{"type":"string","format":"date-time"},"status":{"enum":["unknown","pre_transit","in_transit","out_for_delivery","delivered","available_for_pickup","return_to_sender","failure"]},"message":{"type":"string"},"location":{"type":["string","null"]}},"required":["datetime","status","message","location"]}},"protected":{"type":"boolean"},"claimable":{"type":"boolean","description":"Protected, and no claim is open"},"headline":{"type":"string","description":"The page's headline. Days are relative to UTC","examples":["Arrives Friday","Out for delivery today","Delivered Wednesday"]},"delivered_at":{"type":["string","null"],"description":"The delivery scan's time, as the carrier wrote it"},"delivery_location":{"type":["string","null"],"description":"Where it was left, when the carrier says. Never a name or address","examples":["Front door or porch"]},"problem":{"anyOf":[{"type":"object","properties":{"kind":{"enum":["delayed","exception","failure","return_to_sender","available_for_pickup","cancelled"]},"title":{"type":"string","examples":["Delivery attempted"]},"message":{"type":"string","description":"Plain English: what happened and what the recipient can do"}},"required":["kind","title","message"]},{"type":"null"}],"description":"`null` while the package is going to plan"},"carrier_tracking_url":{"type":["string","null"],"description":"The carrier's own tracking page"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When VeloShip last heard from the carrier"},"store_url":{"type":["string","null"]},"support_email":{"type":["string","null"]}},"required":["object","status","status_label","est_delivery_date","carrier","tracking_code","shipped_by","destination","events","protected","claimable","headline","delivered_at","delivery_location","problem","carrier_tracking_url","updated_at","store_url","support_email"]},"CarrierField":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"required":{"type":"boolean"},"options":{"type":["array","null"],"items":{"type":"string"}},"option_labels":{"type":["object","null"],"additionalProperties":{"type":"string"},"description":"What to show for each option, e.g. `sandbox` as \"Sandbox\""},"default":{"type":["string","null"]},"help":{"type":["string","null"],"description":"One line saying where the value comes from"},"placeholder":{"type":["string","null"]},"show_when":{"anyOf":[{"type":"object","properties":{"field":{"type":"string"},"equals":{"type":"string"}},"required":["field","equals"]},{"type":"null"}],"description":"The field only applies while the settings field `field` holds `equals`; it is ignored otherwise"}},"required":["key","label","required","options","option_labels","default","help","placeholder","show_when"]},"ConnectionCheck":{"type":"object","properties":{"check":{"enum":["auth","rates","address","labels"]},"status":{"enum":["pass","fail","warn","skipped"],"description":"`warn` means it works but needs attention, such as labels that aren't enabled yet; `skipped` means the carrier offers no safe way to check, or an earlier check failed"},"message":{"type":"string","description":"Carrier-sourced and sanitized; never contains credentials"},"hint":{"type":"string","description":"What to do about it"}},"required":["check","status","message"]},"ConnectionTest":{"type":"object","properties":{"object":{"const":"ConnectionTest"},"status":{"enum":["pass","warn","fail"],"description":"The worst of the checks"},"checks":{"type":"array","items":{"$ref":"#/components/schemas/ConnectionCheck"}},"tested_at":{"type":"string","format":"date-time"}},"required":["object","status","checks","tested_at"]},"CarrierCapabilities":{"type":"object","properties":{"services":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"description":{"anyOf":[{"$ref":"#/components/schemas/RateDescription"},{"type":"null"}]}},"required":["code","name","description"]}},"packaging":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"}},"required":["code","name"]},"description":"What `parcel.predefined_package` accepts for this carrier"},"flat_rate":{"anyOf":[{"type":"object","properties":{"name":{"type":"string","examples":["One Rate"]},"packages":{"type":"array","description":"Cheapest first; the optimizer takes the first that fits","items":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"max_weight_oz":{"type":"number"},"dimensions":{"type":"array","items":{"type":"array","items":{"type":"number"},"minItems":3,"maxItems":3},"description":"Interior sizes in inches; a parcel fits if it fits one, in any orientation. Absent for shapeless packaging"},"max_volume_cubic_in":{"type":"number","description":"For size-priced flat rates (UPS Simple Rate): the largest length x width x height that fits, in cubic inches"}},"required":["code","name","max_weight_oz"]}}},"required":["name","packages"]},{"type":"null"}]},"signature_options":{"type":"array","items":{"enum":["none","indirect","direct","adult"]}},"declared_value":{"type":"boolean"},"saturday_delivery":{"type":"boolean"},"returns":{"type":"boolean"},"label_formats":{"type":"array","items":{"enum":["PDF","PNG","ZPLII"]}},"void_window":{"type":"object","properties":{"hours":{"type":["number","null"]},"description":{"type":"string"}},"required":["hours","description"]},"address_verification":{"type":"boolean"},"reconciliation":{"type":"boolean","description":"Labels can be found again by reference, so a lost purchase can be reconciled automatically"},"push_tracking":{"type":"boolean"},"tracking_patterns":{"type":"array","items":{"type":"string"},"description":"Regular expressions for this carrier's tracking numbers"},"international":{"anyOf":[{"$ref":"#/components/schemas/CarrierInternational"},{"type":"null"}],"description":"Shipping across customs borders; `null` when the carrier only ships domestically"}},"required":["services","packaging","flat_rate","signature_options","declared_value","saturday_delivery","returns","label_formats","void_window","address_verification","reconciliation","push_tracking","tracking_patterns","international"]},"Carrier":{"type":"object","properties":{"id":{"type":"string","examples":["fedex"],"description":"Accepted by `carrier` filters"},"object":{"const":"Carrier"},"name":{"type":"string","examples":["FedEx"],"description":"What `carrier` shows on rates, shipments and trackers"},"configured":{"type":"boolean","description":"Whether an enabled account exists for this carrier"},"capabilities":{"$ref":"#/components/schemas/CarrierCapabilities"},"settings_fields":{"type":"array","items":{"$ref":"#/components/schemas/CarrierField"}},"credentials_fields":{"type":"array","items":{"$ref":"#/components/schemas/CarrierField"}}},"required":["id","object","name","configured","capabilities","settings_fields","credentials_fields"]},"CarrierAccount":{"type":"object","properties":{"id":{"type":"string","examples":["ca_01a131ca1cc83766d0ac"],"description":"`ca_env_fedex` is the implicit account made from the FEDEX_* secrets while no FedEx account exists"},"object":{"const":"CarrierAccount"},"carrier":{"type":"string","examples":["FedEx"]},"description":{"type":"string"},"mode":{"enum":["live","test"]},"settings":{"type":"object","additionalProperties":{"type":"string"},"description":"Non-secret settings, such as a FedEx account number"},"has_credentials":{"type":"boolean","description":"Credentials are write-only and never returned; this says whether any are stored"},"enabled":{"type":"boolean"},"implicit":{"type":"boolean","description":"Backed by environment secrets rather than a stored account; read-only"},"last_test":{"anyOf":[{"$ref":"#/components/schemas/ConnectionTest"},{"type":"null"}],"description":"The latest connection test. `null` before the first one, and again after the account's credentials or settings change"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"required":["id","object","carrier","description","mode","settings","has_credentials","enabled","implicit","last_test","created_at","updated_at"]},"Webhook":{"type":"object","properties":{"id":{"type":"string"},"object":{"const":"Webhook"},"url":{"type":"string"},"disabled":{"type":"boolean"},"secret":{"type":"string","description":"Only in the create response. Store it to verify signatures"},"created_at":{"type":"string","format":"date-time"}},"required":["id","object","url","disabled","created_at"]},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"string"},"object":{"const":"WebhookDelivery"},"webhook_id":{"type":"string"},"event_id":{"type":"string"},"event_type":{"enum":["tracker.created","tracker.updated","shipment.purchased","shipment.refunded","shipment.purchase_failed","claim.created","claim.updated","batch.completed","alert.raised","print.job.done","print.job.failed","print.job.rerouted","print.printer.problem","print.printer.recovered","print.station.offline","print.station.online","print.station.updated","webhook.test"]},"event":{"$ref":"#/components/schemas/Event","description":"The event exactly as it was sent. Only when getting one delivery"},"status":{"enum":["pending","retrying","succeeded","failed"]},"attempts":{"type":"integer"},"response_status":{"type":["integer","null"]},"last_error":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","object","webhook_id","event_id","status","attempts","response_status","last_error","created_at","updated_at"]},"ApiKey":{"type":"object","properties":{"id":{"type":"string"},"object":{"const":"ApiKey"},"name":{"type":"string"},"mode":{"enum":["live","test"]},"prefix":{"type":"string"},"key":{"type":"string","description":"Only in the create response"},"scopes":{"type":"array","items":{"enum":["rates:read","shipments:read","shipments:write","protection:manage","settings:write","webhooks:manage","rules:read","rules:write","print:read","print:write","*"]},"description":"`*` is full access"},"daily_label_limit":{"type":["integer","null"]},"daily_spend_limit":{"anyOf":[{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]},{"type":"null"}]},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"usage_today":{"type":"object","properties":{"labels":{"type":"integer"},"spend":{"type":"string","pattern":"^\\d+\\.\\d{2}$","examples":["12.34"]}},"required":["labels","spend"]},"created_at":{"type":"string","format":"date-time"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"created_by":{"type":["string","null"],"description":"The user who created the key; null for keys made with the root key"},"created_by_email":{"type":["string","null"]}},"required":["id","object","name","mode","prefix","scopes","daily_label_limit","daily_spend_limit","expires_at","usage_today","created_at","last_used_at","revoked_at","created_by","created_by_email"]},"AuditEvent":{"type":"object","properties":{"id":{"type":"string"},"object":{"const":"AuditEvent"},"actor":{"type":"string","description":"An API key ID, `root`, or `user_…` for a signed-in member"},"actor_email":{"type":["string","null"],"description":"The member's email when `actor` is a user"},"action":{"type":"string","examples":["label.purchased"]},"target_id":{"type":["string","null"]},"mode":{"enum":["live","test"]},"details":{"type":"object"},"created_at":{"type":"string","format":"date-time"}},"required":["id","object","actor","actor_email","action","target_id","mode","details","created_at"]},"RequestLog":{"type":"object","properties":{"id":{"type":"string","examples":["req_019a1b2c3d4e5f60718293a4b5c6"]},"object":{"const":"RequestLog"},"mode":{"enum":["live","test"]},"created_at":{"type":"string","format":"date-time"},"method":{"type":"string"},"path":{"type":"string","description":"As requested, without the query string"},"route":{"type":["string","null"],"description":"The route it matched, e.g. `/v1/shipments/{id}/buy`; null for unknown paths","examples":["/v1/shipments/:id/buy"]},"query":{"type":["string","null"],"description":"The query string with secrets removed"},"status":{"type":"integer"},"duration_ms":{"type":"integer"},"actor":{"type":"string","description":"An API key ID, `root`, or `user_…` for a signed-in member"},"actor_email":{"type":["string","null"],"description":"The member's email when `actor` is a user"},"idempotency_key":{"type":["string","null"]},"idempotent_replay":{"type":"boolean","description":"The response was replayed from an earlier request with the same key"},"request_id":{"type":["string","null"],"description":"The `x-request-id` the response carried"},"country":{"type":["string","null"],"description":"Two-letter country the request came from"},"user_agent":{"type":["string","null"]},"error_code":{"type":["string","null"],"description":"The `error.code` of an error response"},"scenario":{"type":["string","null"],"description":"The `VeloShip-Scenario` applied to a test-mode request"}},"required":["id","object","mode","created_at","method","path","route","query","status","duration_ms","actor","actor_email","idempotency_key","idempotent_replay","request_id","country","user_agent","error_code","scenario"]},"RequestLogDetail":{"allOf":[{"$ref":"#/components/schemas/RequestLog"},{"type":"object","properties":{"request_body":{"description":"Redacted. Parsed JSON when complete, text when it was cut off at 16 KB or isn't JSON; null for no body"},"request_body_truncated":{"type":"boolean"},"response_body":{"description":"Redacted, like `request_body`. Binary responses (labels) aren't stored"},"response_body_truncated":{"type":"boolean"},"related_object_ids":{"type":"array","items":{"type":"string"},"description":"Shipments, batches, claims and trackers the request named or returned"}},"required":["request_body","request_body_truncated","response_body","response_body_truncated","related_object_ids"]}]},"Me":{"type":"object","properties":{"object":{"const":"Me"},"api_key_id":{"type":"string","description":"The key's ID, `root`, or `user_…` when the request used a session cookie"},"root":{"type":"boolean"},"mode":{"enum":["live","test"]},"scopes":{"type":"array","items":{"type":"string"},"description":"Role-derived sessions also hold `keys:manage`, `audit:read`, `logs:read`, `members:manage`, `org:manage` and `billing:manage`"},"organization_id":{"type":"string"},"user":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"role":{"enum":["owner","admin","member","viewer"]}},"required":["id","email","name","role"]},{"type":"null"}]}},"required":["object","api_key_id","root","mode","scopes","organization_id","user"]},"Organization":{"type":"object","properties":{"object":{"const":"Organization"},"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}},"required":["object","id","name","slug"]},"OrgMember":{"type":"object","properties":{"object":{"const":"OrgMember"},"id":{"type":"string","description":"The membership ID"},"user_id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"role":{"enum":["owner","admin","member","viewer"]},"joined_at":{"type":"string","format":"date-time"}},"required":["object","id","user_id","name","email","role","joined_at"]},"OrgInvitation":{"type":"object","properties":{"object":{"const":"OrgInvitation"},"id":{"type":"string"},"email":{"type":"string"},"role":{"enum":["owner","admin","member","viewer"]},"expires_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"},"invite_url":{"type":"string","description":"Send this to the invitee; they sign in or create an account there and join"}},"required":["object","id","email","role","expires_at","created_at","invite_url"]},"Session":{"type":"object","properties":{"authenticated":{"type":"boolean"},"user":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"email_verified":{"type":"boolean"}},"required":["id","email","name","email_verified"]},{"type":"null"}]},"organizations":{"type":"array","items":{"type":"object","properties":{"organization_id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"role":{"enum":["owner","admin","member","viewer"]}},"required":["organization_id","name","slug","role"]}},"active_organization_id":{"type":["string","null"]},"role":{"type":["string","null"],"enum":["owner","admin","member","viewer",null]},"scopes":{"type":"array","items":{"type":"string"}},"operator":{"type":"boolean","description":"Owner of the first organization: may also read the waitlist"},"billing":{"type":"boolean","description":"Billing is on and applies to the active organization"},"config":{"type":"object","properties":{"configured":{"type":"boolean"},"signup_enabled":{"type":"boolean"},"google_enabled":{"type":"boolean"},"turnstile_site_key":{"type":["string","null"],"description":"Set when sign-up requires a Turnstile challenge"},"email_verification":{"type":"boolean","description":"Whether the server can send verification emails"},"rules_ai":{"type":"boolean","description":"Whether \"Describe a rule in English\" is available: the server has an ANTHROPIC_API_KEY"}},"required":["configured","signup_enabled","google_enabled","turnstile_site_key","email_verification","rules_ai"]}},"required":["authenticated","user","organizations","active_organization_id","role","scopes","operator","billing","config"]},"SignupResult":{"type":"object","properties":{"organization":{"$ref":"#/components/schemas/Organization"},"test_key":{"$ref":"#/components/schemas/ApiKey","description":"The only time the key is visible"},"email_verified":{"type":"boolean"},"email_verification":{"enum":["sent","unavailable"],"description":"`unavailable` when the server has no email binding; the operator then verifies the account"}},"required":["organization","test_key","email_verified","email_verification"]},"Billing":{"type":"object","properties":{"object":{"const":"Billing"},"enabled":{"type":"boolean","description":"False while the server has no billing set up; nothing else is present"},"exempt":{"type":"boolean","description":"The platform's own organization is never billed; nothing else is present"},"plan":{"enum":["free","metered"]},"status":{"type":"string","description":"The subscription's status: `none`, `active`, `trialing`, `past_due`, `canceled`, `unpaid`, …"},"period_start":{"type":"string","format":"date-time"},"period_end":{"type":"string","format":"date-time"},"free_labels":{"type":"integer","description":"Live labels each UTC month before a subscription is needed"},"labels_this_period":{"type":"integer","description":"Live labels bought this period, voided ones excluded"},"billable_labels":{"type":"integer","description":"Of those, the ones beyond the free allowance"},"free_remaining":{"type":"integer"},"can_buy_live_labels":{"type":"boolean"},"past_due_grace_ends_at":{"type":["string","null"],"format":"date-time"},"current_period_end":{"type":["string","null"],"format":"date-time"},"cancel_at_period_end":{"type":"boolean"},"has_customer":{"type":"boolean"}},"required":["object","enabled"]},"BillingSession":{"type":"object","properties":{"object":{"const":"BillingSession"},"url":{"type":"string","description":"Send the person here. Single use and short lived"}},"required":["object","url"]},"OnboardingStep":{"type":"object","properties":{"id":{"enum":["test_key","quickstart","first_label","verify_email","ship_from","carrier","payment_method","go_live"]},"title":{"type":"string"},"detail":{"type":"string"},"done":{"type":"boolean"},"link":{"type":"string","description":"An admin route for the step"},"optional":{"type":"boolean","description":"Doesn't hold up completion"}},"required":["id","title","detail","done"]},"Onboarding":{"type":"object","properties":{"object":{"const":"Onboarding"},"self_serve":{"type":"boolean","description":"Created through sign-up"},"show":{"type":"boolean","description":"Whether the admin shows the checklist: a self-serve organization that isn't finished"},"complete":{"type":"boolean"},"live_ready":{"type":"boolean","description":"Only the first live label is left: the email is verified and a carrier is connected"},"blockers":{"type":"array","items":{"type":"string"}},"steps":{"type":"array","items":{"$ref":"#/components/schemas/OnboardingStep"}}},"required":["object","self_serve","show","complete","live_ready","blockers","steps"]},"InvitationPreview":{"type":"object","properties":{"object":{"const":"InvitationPreview"},"email":{"type":"string"},"role":{"type":["string","null"]},"organization_name":{"type":"string"},"expires_at":{"type":"string","format":"date-time"},"account_exists":{"type":"boolean"}},"required":["object","email","role","organization_name","expires_at","account_exists"]},"Event":{"type":"object","properties":{"id":{"type":"string"},"object":{"const":"Event"},"mode":{"enum":["live","test"]},"type":{"enum":["tracker.created","tracker.updated","shipment.purchased","shipment.refunded","shipment.purchase_failed","claim.created","claim.updated","batch.completed","alert.raised","print.job.done","print.job.failed","print.job.rerouted","print.printer.problem","print.printer.recovered","print.station.offline","print.station.online","print.station.updated","webhook.test"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object"}},"required":["id","object","mode","type","created_at","data"]},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","examples":["PARAMETER.INVALID"]},"message":{"type":"string"},"details":{"description":"Present when there's something to list, such as invalid fields"},"shipment_id":{"type":"string","description":"Set when a create-and-buy call created the shipment but the purchase failed"}},"required":["code","message"]}},"required":["error"]}}}}