Large changes travel as CSV files, never inside a request: upload the file, let Tringify analyze it exactly like the Store Admin import wizard, review what would change, then confirm. The reference for every endpoint is CSV imports and exports.
When to use CSV imports#
Use a CSV import when a change touches more records than one request should carry: a catalog of thousands of products, a price update across a range, a customer migration or a whole language of translations. The file travels through an upload URL, Tringify analyzes it exactly like the Store Admin import wizard, and nothing changes until you confirm. Exports work the other way: start one, then download the file from a short-lived link. Store Admin API tokens and connected AI tools can use these endpoints; app tokens cannot.
Import in five steps#
Check the type:
GET /imports/typeslists every import, itsmodes(the first is the default), itsoptionsand the scopes it needs.Upload the file:
POST /imports/upload-intentswith thetype(andresourcefor translations) and one item describing the file. PUT the file's bytes to the returnedupload_url, then callPOST /imports/upload-intents/finalizeand pollPOST /imports/upload-intents/statusuntil the intent isready; both take thetypeand theintent_idsonly (the intent keeps theresourcegiven when it was created). The type's Store Admin limits on size, rows and columns apply here.Create the import:
POST /importswith the readyfile_id, themodeand any options. The response is the import in preview, withstatusreadyorblocked.Review the preview: show the counts (
creates,updates,unchanged,skips,errors), thewarnings(for example ignored columns) and the row errors fromGET /imports/{importId}/errorsbefore going on.Confirm:
POST /imports/{importId}/confirmstarts the job. PollGET /imports/{importId}untilstatusiscompleted,failedorcancelled;jobcarries the progress and the result counts, and the errors endpoint now returns the rows the job could not apply.
POST /api/2025-01/imports
Idempotency-Key: catalog-update-2026-10-27
{
"type": "products",
"file_id": "5d3a1c7e-2f4b-4a6c-8e9d-0b1c2d3e4f5a",
"mode": "update_only",
"options": { "create_redirects": true }
}
201 Created
{
"success": true,
"data": {
"import": {
"id": "3f0c9a1e-6b2d-4e8f-9a7c-1d2e3f4a5b6c",
"type": "products",
"mode": "update_only",
"status": "ready",
"preview": { "rows": 1200, "creates": 0, "updates": 1180, "unchanged": 14, "skips": 0, "errors": 6, "can_confirm": true },
"job": null,
"expires_at": "2026-10-28T14:02:00-04:00"
}
}
}
A preview stays valid for 24 hours. Analyzing a large file can take up to 25 seconds; when the service is busy the request returns 503 and can be repeated with the same Idempotency-Key. Send an Idempotency-Key on every create so a retry after a timeout returns the same import instead of a second one.
Rows with errors#
Most types need an error-free file: when the preview has errors, can_confirm is false and status is blocked. Fix the rows the errors endpoint lists, upload the file again and create a new import. Imports marked partial (reviews, historical orders and translations) apply the valid rows and skip the rest, as the Store Admin wizard does. Each error names the CSV row, the field and, when it maps to one, the column header as your file shows it, plus a code, a message and, when the error has them, details (for example existing_id, the resource that already holds a duplicate value).
A problem with the whole file is listed the same way, on row 1 (the header row), with field naming the column: a missing required column (IMPORT_EXPORT_CSV_MISSING_REQUIRED_COLUMN, one error per column), a duplicate, blank or unsupported column, a file over the type's size, row or column limits, or a plan limit the file would exceed. Update files need the ID column of an export, and for categories and attributes also its Revision column.
An unchanged export imports again without errors in the type's update mode. Attributes export one row per option with the attribute's fields on every row; that file imports with update_attribute_options, or with update_attributes to change attribute fields only, where option cells that still match the store are ignored and an edited option cell is a row error. An attribute takes its fields from its first row: a later row whose field differs from both the first row and the stored value is ATTRIBUTE_IMPORT_FIELD_CONFLICT. Stock level rows need a Reason only where Quantity changes, and redirects the store already has are skipped. Reviews, tags and historical orders only add records, so their export is a file to move data to another store, not to edit in place.
A translation import's preview runs exactly the checks the job runs, with the same uniqueness rule as the translation API: per language, category names are unique among categories with the same parent, slugs (and vendor, brand, blog category and blog tag names) among the values shown in that language, and tag and attribute names among translated names. Two rows of one file that would share a value: the earlier row keeps it and the later row is an error. A row the preview accepts fails in the job only if the store changed in between, and then with its real code, never a generic one. The job applies the file in batches of at most 500 rows, each checked in one pass and saved in its own short transaction, so a running import does not hold up other translation writes: a write of another resource type, another language or another value never waits for it, and a write that touches an item or a name or slug the current batch is writing waits at most 2 seconds and otherwise fails with TRANSLATION_WRITE_BUSY (nothing saved; send it again after error.details.retry_after_seconds).
Gift Card CSV files#
For Gift Cards, use type gift_cards. Import issues a new card for each row and requires Currency, Amount and Reason; it cannot update existing cards. A preview with any error cannot be confirmed. Delivery defaults to manual (nothing is sent); sending choices come from Gift Card settings and require the matching recipient email or phone. Send at and Expires at must be future RFC 3339 timestamps with an offset; a scheduled delivery must be sent, and expiry must be after delivery. Card amounts and text use the limits returned by Get Gift Card limits. Codes are generated by Tringify and never appear in CSV files or row errors. Retrying or resuming one import never issues its rows twice; uploading the file as a new import issues new cards. Imports can be cancelled, but cards already issued remain and there is no undo. Export lists cards newest first with only Code (last 4), balances, recipient details, status, source, language and RFC 3339 dates in the store timezone.
Use write_gift_cards to upload and confirm an import, and read_gift_cards to read its progress or export cards. These CSV endpoints support Store Admin tokens and connected tools. The Gift Card preview checks every row; failures after confirmation appear in the job's row errors while other rows continue. Job error counts include every failed row; row_error_limit and the failed-row count show when only the first errors are retained. Cancelling stops later batches; a batch already issuing may finish. Every new card has the same issuance history, audit entry, delivery and gift_cards/create webhook as Issue a Gift Card. No code is included in a CSV result or webhook.
Import column |
Field |
Required |
|---|---|---|
Currency |
|
Required |
Amount |
|
Required |
Reason |
|
Required |
Recipient name |
|
Optional |
Recipient email |
|
Optional |
Recipient phone |
|
Optional |
Message |
|
Optional |
Language |
|
Optional |
Delivery |
|
Optional |
Send at |
|
Optional |
Expires at |
|
Optional |
Currency must be the store's base currency or an enabled currency. Amount must be positive and within issue_max and the currency's precision; Reason is required and stays in merchant history. Recipient name and Message follow the text limits in Get Gift Card limits. Recipient email must be valid; Recipient phone needs its country calling code. Language must be offered by the store; blank uses its default. Delivery can be manual, email, phone or both, when offered in delivery_options. Sending needs the matching recipient details. Blank Send at sends immediately when a sending method is chosen; a future Send at keeps the card scheduled until then. Blank Expires at adds no expiry. Import headers are matched case-insensitively. An export is a record of existing cards and is not an update template.
Export columns, in order: ID, Code (last 4), Currency, Initial value, Balance, Status, Source, Order ID, Recipient name, Recipient email, Recipient phone, Message, Language, Issued at, Activated at, Expires at, Send at, Updated at. Export is a background operation over pages; values reflect the cards when each page is read. Files use UTF-8 with a BOM and escape spreadsheet formulas, as other CSV exports do.
Gift Card row error |
Message (parameters filled by the server) |
|---|---|
|
{{.column}} is required. |
|
{{.column}} must be more than 0 and at most {{.max}}, with at most {{.decimals}} decimal places. |
|
{{.column}} can have at most {{.max}} characters. |
|
{{.column}} must be a valid email address. |
|
{{.column}} must be a phone number with its country calling code, like +15551234567. |
|
{{.column}} must be a future date and time, like 2026-12-24T09:00:00+01:00. |
|
{{.column}} must be after Send at. |
|
{{.column}} must be one of: {{.options}}. |
|
{{.column}} is required for this delivery. |
|
Issue Gift Cards in the store's base currency or another enabled store currency. {{.currency}} is not enabled. |
|
Choose one of your store's languages. |
|
{{.column}} isn't a Gift Card import column. Remove it or use the import template. |
Import types#
Type |
Records |
Modes |
Options |
Scopes to run |
Supports |
|---|---|---|---|---|---|
|
Products |
|
|
|
cancel |
|
Product sales baselines |
— |
— |
|
cancel |
|
Categories |
|
|
|
cancel |
|
Attributes |
|
— |
|
cancel |
|
Product tags |
— |
— |
|
cancel |
|
Vendors |
|
|
|
cancel |
|
Brands |
|
|
|
cancel |
|
Customers |
|
— |
|
cancel |
|
Gift Cards |
— |
— |
|
cancel |
|
Reviews |
— |
— |
|
partial, cancel |
|
Historical orders |
— |
— |
|
partial, cancel, undo |
|
Stock levels |
— |
— |
|
cancel |
|
Inventory groups |
— |
— |
|
cancel |
|
Locations |
|
— |
|
cancel |
|
Menu items |
|
— |
|
cancel |
|
URL redirects |
— |
— |
|
cancel |
|
Tax rates |
|
|
|
cancel |
|
Translations |
— |
|
|
partial |
The first mode is the default. These modes and options are exactly what POST /imports accepts, from the same catalog the importer checks; any other mode is IMPORT_EXPORT_INVALID_MODE naming the type's modes.
Discard, cancel and undo#
POST /imports/{importId}/discard drops an import that was not confirmed. Reviews, tags, historical orders, sales baselines and tax rates keep one waiting preview per store, so discard an unwanted one before creating another (IMPORT_EXPORT_PREVIEW_ALREADY_ACTIVE). POST /imports/{importId}/cancel stops a running job; rows already applied stay applied. A finished historical order import can be undone with POST /imports/{importId}/undo: the first call returns CONFIRMATION_REQUIRED with how many orders will be deleted and how many changed since the import and are kept; repeat it with confirmed: true and the confirmation_token after the merchant agrees. One call deletes a bounded batch, so repeat the round while remaining is above 0.
Exports#
POST /exports with a type and its options starts the same export as the Export button in Store Admin. Poll GET /exports/{exportId} until status is completed; the response then carries download_url, a signed link valid for 5 minutes. Read the export again for a fresh link. Export files use the import columns, so an edited export can be imported again, except Gift Cards: their export is a listing (no Amount or Reason, only the last 4 code characters) and their import only issues new cards.
Type |
Records |
Options |
Scopes |
|---|---|---|---|
|
Products |
|
|
|
Categories |
— |
|
|
Attributes |
|
|
|
Product tags |
— |
|
|
Vendors |
— |
|
|
Brands |
— |
|
|
Customers |
— |
|
|
Newsletter subscribers |
— |
|
|
Gift Cards |
— |
|
|
Reviews |
— |
|
|
Orders |
— |
|
|
Stock levels |
|
|
|
Stock history |
|
|
|
Inventory groups |
— |
|
|
Locations |
— |
|
|
Menu items |
— |
|
|
URL redirects |
— |
|
|
Tax rates |
|
|
|
Tax rate reference |
|
|
|
Tax zones |
|
|
|
Tax classes |
|
|
|
Translations |
|
|
Translate a whole language#
Export the source and current translations:
POST /exportswithtype: "translations"andoptions: { "resource": "product", "locale": "fr" }, then download the file.Translate the file, keeping its id columns and headers.
Upload it with
type: "translations"andresource: "product", thenPOST /importswith the sameresourceandlocaleoptions.Review the preview (new translations count as
creates, overwritten ones asupdates) and confirm.
Translation resources: attribute, attribute_option, blog_author, blog_category, blog_category_metafield, blog_post, blog_post_metafield, blog_tag, brand, brand_metafield, category, category_metafield, collection, collection_metafield, menu_item, metafield_choice, metafield_definition, page, page_metafield, product, product_filter_definition, product_media, product_metafield, store_metafield, tag, variant, variant_metafield, vendor, vendor_metafield. The locale must be an enabled, non-default store language.
Translation CSV resources include message_template (one SMS or WhatsApp message type and channel; content), email_template (one email editor text per row; content), order_status (one custom status; name), file and product_media (alt_text). Email text_id is the template UUID followed by : and the exact text_key from the export: subject, preview_text, preheader, a reachable block text or a code-mode text run. Keep these identifiers, source columns and headers unchanged; edit only translated columns. Email translations change text, preserving layout and template syntax. Message and email translations must keep every {{ ... }} value and {% ... %} tag. Blank cells keep stored translations; __CLEAR__ clears one. System order statuses are supplied by Tringify and cannot be translated. The preview, row errors, file limits and job progress are the same as other translation CSVs.
Translation resource |
CSV columns |
|---|---|
|
|
|
|
|
|
|
|
|
|
For emails, the export supplies the exact editor text identifiers; no separate per-email Store API translation endpoint is offered. Send type translations with resource email_template through the ordinary CSV workflow. Email subjects, preview text, preheaders, reachable visual block texts and code-mode text runs retain their editor granularity. Standard AI Translator jobs are available in Store Admin and mobile, using the same estimates, credits, progress, review and apply flow as other translation resources. Theme text keeps its storefront/theme-scoped translation workflow and CSV format; it is not a resource option of these CSV endpoints.
Connected AI tools#
The hosted MCP server offers the same steps as tools: list_import_types, create_import_upload, finalize_import_upload, get_import_upload_status, create_import, list_import_errors, confirm_import, get_import, list_imports, discard_import, cancel_import, undo_import, list_export_types, create_export, get_export, list_exports and cancel_export. The tool uploads and downloads the file with its own HTTP client; file contents never go into tool arguments or replies. A tool is listed when the connection has any permission an import or export type needs, and each call needs that type's permissions.