Export and import data
AI agents: read /llms.txt; add .md to any page URL. This page as Markdown: /guides/imports-and-exports.md. Index of every page and the rules for every call: /llms.txt. Guides and concepts in one file: /llms-full.txt. OpenAPI: /openapi.json.
Export whole-team data
Section titled “Export whole-team data”Large exports, such as every sales order in a quarter, run in the background. You start one, wait for it to be ready, then download the file.
- Start itThe answer has the export’s
id - pendingWaiting its turn
- generatingYoPrint builds the file
- readyDownload the file
-
See which exports exist, and the columns and options each takes:
GET List export types and their columns/v1/ api/ store/ {team_slug}/ data_export/ definitions -
Start an export. For example, sales orders:
POST Export sales orders in a date range to CSV/v1/ api/ store/ {team_slug}/ data_export/ export_sales_order {"start_date": "2026-10-01T00:00:00Z","end_date": "2026-12-31T23:59:59Z","date_field": "issue_date","idempotency_key": "so-export-2026-q4"}The answer is the export, with its
idandstatus. -
Check it until
GET Get a data exportstatusisready. It moves frompendingtogenerating, then toreadyorfailed./v1/ api/ store/ {team_slug}/ data_export/ {id} -
Download the file, with the export’s
GET Download a data export's fileid. The answer is the file itself, not JSON, so save it:/v1/ api/ store/ {team_slug}/ data_export/ {id}/ download Terminal window curl -o sales-orders.csv \"https://secure.yoprint.com/v1/api/store/your-team/data_export/R38ZQ52Wx5meqn/download" \-H "Authorization: Bearer YOUR_API_KEY" \-H "Accept: application/json" \-H "X-Yoprint-Decimal-Format: exact-v1"
The other exports work the same way: customers, invoices, invoice items, payments, purchase orders, taxes, simple products and variant products.
POST Export all customers to CSV/v1/api/store/{team_slug}/data_export/export_customer
POST Export invoices in a date range to CSV /v1/api/store/{team_slug}/data_export/export_invoice
POST Export payments and refunds in a date range to CSV /v1/api/store/{team_slug}/data_export/export_payment_list
- Exports over a date range need
start_dateandend_date, with the end on or after the start. The sales order export also needsdate_field, the order date the range applies to:issue_date,deposit_due,due_date,ship_due_date,cust_due_dateorstart_date. columnspicks the columns, from the export’s definition.idempotency_key, up to 100 characters, makes the start safe to retry: the same key returns the same export instead of starting another. After a failure to queue, or an expired attempt, the same key queues it again. See Retries and duplicates.- Downloading before the export is ready answers
404.
A team can run 3 exports at once, and one of each kind. See Limits. To list your team’s exports:
GET List data exports/v1/api/store/{team_slug}/data_export
Quick CSV exports
Section titled “Quick CSV exports”Some lists come straight back as a CSV file, without queueing. They take a date range:
POST Export sales orders as CSV/v1/api/store/{team_slug}/sales_order/export
POST Export purchase orders by issue date /v1/api/store/{team_slug}/purchase_order/export
{ "start_date": "2026-11-01T00:00:00Z", "end_date": "2026-11-30T23:59:59Z" }They don’t always answer with a file:
- With
"list_only": true, the rows come back as JSON instead, and an empty range answers an emptydatalist. - Without
list_only, when nothing matches the date range, the answer is JSON422(sales_order_export_errororpurchase_order_export_error), not an empty file.
Check the status and Content-Type before you save the body.
Documents
Section titled “Documents”PDFs and printable files for chosen records:
POST Download invoices as one PDF/v1/api/store/{team_slug}/invoice/export_pdf
POST Download job details (PDF) /v1/api/store/{team_slug}/job/export_job_detail
POST Download packing slips (PDF) /v1/api/store/{team_slug}/shipment/export_packing_slip
These answer with the file itself, not JSON. Save the response body.
Import service pricing
Section titled “Import service pricing”The public API imports one kind of CSV file: service pricing, a decoration service’s price table. An import either replaces the prices of a service you have (target_mode existing_service), or creates a new service with those prices (create).
-
Download an example file to fill in:
PUT Download the service pricing CSV template/v1/ api/ store/ {team_slug}/ csv/ template/ service_pricing qty/type,1 Color,2 Colors1,12.50,15.0024,8.00,10.00- The file: a UTF-8
.csv, at most 6,240 KB and 600 data rows. - Headers: exactly
qty/typefirst, then one column per option, such as1 Color. - Rows: one price break each, starting with its quantity. The first row’s is 1, and no quantity repeats.
- Prices: every cell has one, a decimal number with at most 3 decimal places (
12.50), or two separated by a bar,first|additional(12.50|9.00). - Writing numbers: a digit before the point (
0.50, not.50), and no leading or trailing spaces. See Money and quantities.
- The file: a UTF-8
-
Upload it as a form (
POST Import a service's price table from CSVmultipart/form-data, not JSON):/v1/ api/ store/ {team_slug}/ imports/ csv To replace an existing service’s prices:
Terminal window curl https://secure.yoprint.com/v1/api/store/your-team/imports/csv \-H "Authorization: Bearer YOUR_API_KEY" \-H "Accept: application/json" \-H "X-Yoprint-Decimal-Format: exact-v1" \-F entity_type=service_pricing \-F target_mode=existing_service \-F service_id=V4keXwwxMQyXw7 \-F file=@service-pricing.csvTo create a new service instead, send
target_mode=createwith itsname,allow_cust_loc(1or0),pricing_type(single,additionalorsingle_flat), and at least one print location inlocations:Terminal window curl https://secure.yoprint.com/v1/api/store/your-team/imports/csv \-H "Authorization: Bearer YOUR_API_KEY" \-H "Accept: application/json" \-H "X-Yoprint-Decimal-Format: exact-v1" \-F entity_type=service_pricing \-F target_mode=create \-F "name=Screen print, 1 color" \-F allow_cust_loc=1 \-F pricing_type=single \-F "locations[0][id]=BkzhmfgkK2HFTs" \-F file=@service-pricing.csvLocation ids come from your team’s print locations:
GET List service locations/v1/ api/ store/ {team_slug}/ service_location No public operation lists services, so take an existing service’s id from a job’s services.
-
Read the answer. The import runs while you wait, and the answer is the finished import. It’s all or nothing:
422: the file broke a rule. The answer names the first problem found (with its line, for a row problem), and nothing is saved.500({ "message": "Server Error" }), also saving nothing: a price or quantity written like.50or with a leading space, or a second upload for the same service (or the same new service name) that waited 45 seconds while the first was still running.
Fix the file, or wait, and upload it again.
To read an import again later:
GET Get an import job/v1/ api/ store/ {team_slug}/ imports/ {hash_id}
Replacing an existing service’s prices replaces its whole price table: options and price breaks missing from the file are removed. Service pricing imports never create a file of failed rows, so the error-file operation answers 404 for them.
Pitfalls
Section titled “Pitfalls”- CSV cell errors stop the whole import. Prices must be decimal numbers with at most 3 decimal places (such as
12.50). A cell with an invalid price, missing value, duplicate quantity, or more than 3 decimal places answers422with the line number and saves nothing. Formatting traps that cause500server errors: writing.50without a leading0, or including spaces around numbers. - Upload and request errors. Missing required parameters (
service_idforexisting_service, orname,pricing_type,allow_cust_locandlocationsforcreate) fails with422. Uploading while another import runs on the same service can time out with500after 45 seconds. Service pricing imports never create a file of failed rows. Downloading one answers404. - Downloads aren’t JSON, until they fail. Export downloads, CSVs and PDFs answer with the file, but an error, or a quick export with nothing in range, answers JSON. Check the status first.
- Wait for
ready. A download before then answers404. That doesn’t mean the export is lost. - One of each kind at a time. Starting a second sales order export while one runs answers
422withduplicate_report. - Uploads are forms. The CSV import takes
multipart/form-data, not JSON. - Dates are UTC. A range that should cover whole days in the shop’s timezone has to be converted.
