GL importer

v1.0.1

Import CSV/XLSX accounting data into QuickBooks Online or Xero via the Synder Importer REST API. Use when asked to import invoices, bills, journal entries, c...

2· 250· 2 versions· 0 current· 0 all-time· Updated 1h ago· MIT-0

Synder Importer API

Import CSV/XLSX files into QuickBooks Online or Xero.

Setup

Getting an API Token

If the user doesn't have a token yet, guide them through these steps:

  1. Create an account at importer.synder.com and confirm your email
  2. Connect your accounting software — in the web UI, link QuickBooks Online or Xero via OAuth
  3. Generate an API key — go to Account → API Keys, click Generate. Copy the token immediately — it's shown only once
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.

Data Privacy

  • Homepage: importer.synder.com | Docs: importer.synder.com/apidocs
  • Operator: Synder Technologies Inc. — synder.com
  • What's sent: CSV/XLSX files containing accounting data (invoices, bills, journal entries, etc.) are uploaded to importer.synder.com and forwarded to your connected accounting provider (QuickBooks Online or Xero)
  • Retention: Uploaded files are stored for import processing only and are not retained after import completion. Import logs (row counts, status, error messages) are retained for your account history.
  • Scope: API tokens are scoped to a single user account and its connected companies. Tokens can be revoked at any time from the web UI.
  • Recommendation: Always use dryRun=true first to preview before importing live data. Use non-production data for initial testing.

Quick Reference

ActionMethodEndpoint
Account infoGET/account
List companiesGET/companies
Company settingsGET/POST/companies/{id}/settings
List entitiesGET/companies/{id}/entities
Entity fieldsGET/companies/{id}/entities/{name}/fields
Create mappingPOST/companies/{id}/mappings
List mappingsGET/companies/{id}/mappings
Update mappingPUT/companies/{id}/mappings/{mid}
Delete mappingDELETE/companies/{id}/mappings/{mid}
Execute importPOST/companies/{id}/imports
Auto-importPOST/companies/{id}/imports/auto
List importsGET/companies/{id}/imports
Import statusGET/companies/{id}/imports/{iid}
Cancel importPOST/companies/{id}/imports/{iid}/cancel
Revert importPOST/companies/{id}/imports/{iid}/revert
Import resultsGET/companies/{id}/imports/{iid}/results

Core Workflow

1. Find the company

curl "$BASE/companies" -H "Authorization: Bearer $IMPORTER_API_TOKEN"

Response is an array. Pick the company with status: "ACTIVE". Save its id.

2. Choose entity and check fields

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.

3. Option A: Smart Auto-Import (recommended)

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.

3. Option B: Manual Mapping

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 name
  • targetFieldId: from the fields endpoint
  • fixedValue: constant value for every row (set sourceFieldTitle to null)

4. Upload and Execute Import

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.

5. Poll for Completion

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.

6. Check Results

# 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.

File Requirements

  • CSV: UTF-8, comma-delimited, header row required, max 50MB
  • XLSX: First sheet by default (use sheetName param for others), header row required, max 50MB

Error Handling

All errors return {"error": {"code": "...", "message": "..."}}.

CodeHTTPAction
UNAUTHORIZED401Check/refresh API token
NOT_FOUND404Verify company/mapping/import/entity ID
BAD_REQUEST400Check request format, file validity, provider connection
VALIDATION_ERROR422Map all required fields — call GET .../fields to see which
DUPLICATE_REQUEST409Same Idempotency-Key reused within 24h — use new UUID
CONFLICT409Import not in valid state for cancel/revert
RATE_LIMITED429Wait Retry-After header seconds, then retry

Rate Limits

  • Standard: 60 requests/minute per account
  • Imports: 30 imports/hour per company

Check X-RateLimit-Remaining header. On 429, wait Retry-After seconds.

Tips

  • Use dryRun=true on auto-import before committing — all operations hit live accounting data
  • Revert mistakes with POST .../imports/{id}/revert (deletes created entities from QBO/Xero)
  • alternativeTitles on fields show what CSV headers auto-mapping recognizes
  • For multi-line entities (invoices with line items), use a grouping field (DocNumber) — rows with same value become one entity
  • Paginated endpoints accept page and perPage (max 100, default 20)

Full API Details

For complete field schemas, response examples, and OpenAPI spec: see references/api.md

Version tags

latestvk97342excxr97x0b0hbzzhexen82rnk9