Import CSV/XLSX files into QuickBooks Online or Xero.
If the user doesn't have a token yet, guide them through these steps:
export IMPORTER_API_TOKEN="your_token_here"
export BASE="https://importer.synder.com/api/v1"
> Trial users: Imports are limited by row count without a paid subscription. No subscription is required to use the API itself.
dryRun=true first to preview before importing live data. Use non-production data for initial testing.| Action | Method | Endpoint |
|---|---|---|
| -------- | -------- | ---------- |
| Account info | GET | /account |
| List companies | GET | /companies |
| Company settings | GET/POST | /companies/{id}/settings |
| List entities | GET | /companies/{id}/entities |
| Entity fields | GET | /companies/{id}/entities/{name}/fields |
| Create mapping | POST | /companies/{id}/mappings |
| List mappings | GET | /companies/{id}/mappings |
| Update mapping | PUT | /companies/{id}/mappings/{mid} |
| Delete mapping | DELETE | /companies/{id}/mappings/{mid} |
| Execute import | POST | /companies/{id}/imports |
| Auto-import | POST | /companies/{id}/imports/auto |
| List imports | GET | /companies/{id}/imports |
| Import status | GET | /companies/{id}/imports/{iid} |
| Cancel import | POST | /companies/{id}/imports/{iid}/cancel |
| Revert import | POST | /companies/{id}/imports/{iid}/revert |
| Import results | GET | /companies/{id}/imports/{iid}/results |
curl "$BASE/companies" -H "Authorization: Bearer $IMPORTER_API_TOKEN"
Response is an array. Pick the company with status: "ACTIVE". Save its id.
Common entities: Invoice, Bill, JournalEntry, Customer, Vendor, Expense, SalesReceipt, Payment, CreditMemo
curl "$BASE/companies/$CID/entities/$ENTITY/fields" -H "Authorization: Bearer $IMPORTER_API_TOKEN"
Fields with isRequired: true MUST be mapped. Fields with isForGrouping: true (e.g., DocNumber) combine multiple CSV rows into one entity (multi-line invoices).
> Important: Check GET /companies/{id}/settings for dateFormat (e.g., MM/dd/yyyy). CSV date columns must match this format or the import will fail. Update with POST /companies/{id}/settings if needed.
Skip manual mapping — auto-match CSV headers to fields:
curl -X POST "$BASE/companies/$CID/imports/auto" \
-H "Authorization: Bearer $IMPORTER_API_TOKEN" \
-F "file=@data.csv" \
-F "entityName=Invoice" \
-F "dryRun=true"
dryRun=true (default): Returns proposed mapping without importing. Check missingRequired array — if empty, safe to import. Response: proposedFields, missingRequired, totalFieldsMapped.dryRun=false: Maps AND imports in one call. Returns {"id": "42", "status": "SCHEDULED", "mappingId": "33", ...} — use the id to poll for completion (same as step 5).Confidence levels in proposedFields: high = exact title match, medium = matched via alternative title. Review medium matches before importing with dryRun=false.
Create a mapping linking CSV columns to entity fields:
curl -X POST "$BASE/companies/$CID/mappings" \
-H "Authorization: Bearer $IMPORTER_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "My Invoice Mapping",
"entityName": "Invoice",
"fields": [
{"sourceFieldTitle": "Invoice #", "targetFieldId": "231"},
{"sourceFieldTitle": "Customer", "targetFieldId": "176"},
{"sourceFieldTitle": null, "targetFieldId": "234", "fixedValue": "Imported via API"}
]
}'
sourceFieldTitle: CSV column header nametargetFieldId: from the fields endpointfixedValue: constant value for every row (set sourceFieldTitle to null)curl -X POST "$BASE/companies/$CID/imports" \
-H "Authorization: Bearer $IMPORTER_API_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-F "file=@data.csv" \
-F "mappingId=$MAPPING_ID"
Returns 202 with status: "SCHEDULED". Always send Idempotency-Key to prevent duplicate imports on retry.
curl "$BASE/companies/$CID/imports/$IMPORT_ID" -H "Authorization: Bearer $IMPORTER_API_TOKEN"
Terminal statuses: FINISHED, FINISHED_WITH_WARNINGS, FAILED, CANCELED.
Poll with exponential backoff: start 2s, multiply 1.5x, cap 30s.
# All results
curl "$BASE/companies/$CID/imports/$IMPORT_ID/results" -H "Authorization: Bearer $IMPORTER_API_TOKEN"
# Errors only
curl "$BASE/companies/$CID/imports/$IMPORT_ID/results?type=ERROR" -H "Authorization: Bearer $IMPORTER_API_TOKEN"
Result types: INFO (success), WARNING, ERROR.
sheetName param for others), header row required, max 50MBAll errors return {"error": {"code": "...", "message": "..."}}.
| Code | HTTP | Action |
|---|---|---|
| ------ | ------ | -------- |
| UNAUTHORIZED | 401 | Check/refresh API token |
| NOT_FOUND | 404 | Verify company/mapping/import/entity ID |
| BAD_REQUEST | 400 | Check request format, file validity, provider connection |
| VALIDATION_ERROR | 422 | Map all required fields — call GET .../fields to see which |
| DUPLICATE_REQUEST | 409 | Same Idempotency-Key reused within 24h — use new UUID |
| CONFLICT | 409 | Import not in valid state for cancel/revert |
| RATE_LIMITED | 429 | Wait Retry-After header seconds, then retry |
Check X-RateLimit-Remaining header. On 429, wait Retry-After seconds.
dryRun=true on auto-import before committing — all operations hit live accounting dataPOST .../imports/{id}/revert (deletes created entities from QBO/Xero)alternativeTitles on fields show what CSV headers auto-mapping recognizespage and perPage (max 100, default 20)For complete field schemas, response examples, and OpenAPI spec: see references/api.md
共 1 个版本