Sail

Push Transactions (BYO data)

POST/users/{user_id}/connections/{connection_id}/transactions

Ingest a batch of raw transactions into an external connection for HSA-eligibility enrichment. Idempotent on external_transaction_id within the connection: re-pushed ids update the stored transaction and re-adjudicate. Returns 202. Enrichment results arrive via transactions.ingested webhooks and are read from /users/{user_id}/expenses. Requires the ingest key scope, a write scope with no product counterpart, so read-only keys can never push data. Calling this on a Sail-managed connection returns 409 connection_not_external.

Path Parameters

user_idstringrequired

The Sail user id.

connection_idstringrequired

The Sail connection id.

Body application/json

transactionsobject[]required

Batch of transactions to ingest, up to 500 per request.

Show transactions properties
external_transaction_idstringrequired

Customer’s stable id for this transaction. Idempotency key within the connection.

datestring<date>required

Transaction date.

amountnumber<float>required

Positive decimal; purchases only.

descriptionstringrequired

Raw bank descriptor.

merchant_namestring

Merchant name, if known. Null otherwise.

mccstring

Merchant category code, if known.

currencystring

ISO 4217 currency code.

Response

Batch accepted for enrichment.

statusstring

The batch’s processing status.

job_idstring

Identifier for tracking this ingestion job.

acceptedinteger

New transactions queued for enrichment.

duplicates_updatedinteger

Rows whose external_transaction_id already existed; updated and re-adjudicated.

connection_not_external: transactions can only be pushed to external connections.

Standard error envelope covering 400, 401, 403, 404, 429, and 500.

errorobject

The error detail.

Show error properties
codestring

Machine-readable code, e.g. not_found, token_scope_mismatch, product_not_enabled, insufficient_key_scope, insufficient_token_scope, user_token_required, user_token_expired, invalid_user_token, invalid_key_configuration, connection_not_reconnectable, rate_limited.

messagestring

Human-readable error message. May change, so match on error.code instead.

paramstring

The request field that caused the error, when applicable. Null otherwise.

Request
curl -X POST "https://live.savewithsail.com/api/v1/users/<user_id>/connections/<connection_id>/transactions" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
  "transactions": [
    {
      "external_transaction_id": "acme-tx-1001",
      "date": "2024-01-01",
      "amount": 0,
      "description": "WALGREENS #4821 RX",
      "merchant_name": "string",
      "mcc": "string",
      "currency": "USD"
    }
  ]
}'
Response
{
  "status": "processing",
  "job_id": "string",
  "accepted": 0,
  "duplicates_updated": 0
}