Agent platform · REST

ISO360 API

A REST API for ISO360 agent offices. Push a merchant statement and get a rate analysis back as a proposal in your office; read your boarding applications. One bearer key per office, JSON in and out, over HTTPS.

Overview

Introduction

Every ISO360 API call is authenticated with a bearer key that belongs to a single agent office. The key carries the office identity, so you never pass an office or agent id in a request — whatever you create lands under the office that owns the key.

  • Base URL: https://www.cygma.cloud/api/v1
  • Auth: Authorization: Bearer <key> on every request.
  • Format: JSON responses; uploads use multipart/form-data.
Bearer key, per office

Authentication

Generate your key in ISO360 under My Office → ISO360 API. The full secret is shown once at generation — store it somewhere safe; it can’t be retrieved again. Regenerating immediately invalidates the previous key.

  • Send it as Authorization: Bearer <key>. Treat it like a password — server-side only, never in client code.
  • Each key is scoped (e.g. proposals:create) and rate-limited per minute. Exceeding the limit returns 429.
  • Lost or leaked a key? Regenerate it — the old one stops working instantly.
# Every request carries your office key as a bearer token.
curl https://www.cygma.cloud/api/v1/applications \
  -H "Authorization: Bearer epi_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
2 steps

Quickstart

  1. Create your office key in My Office → ISO360 API.
  2. POST a statement PDF (plus the merchant name) to Analyze a statement. The response carries the parsed numbers and a link to the proposal it created under your office.
# 1. Grab your office key from My Office → ISO360 API.
# 2. Push a statement and read the analysis back.
curl -X POST https://www.cygma.cloud/api/v1/proposals/analyze-statement \
  -H "Authorization: Bearer <your-key>" \
  -F "statement=@statement.pdf;type=application/pdf" \
  -F "merchant_name=Jane's Coffee LLC" \
  -F "mcc=5812"
POST /api/v1/proposals/analyze-statement

Analyze a statement

Uploads a merchant’s prior-processing statement and returns a rate analysis. The call also creates a lead and a draft proposalin the office that owns the key, so the analysis is waiting in ISO360 when your agent logs in.

Requestmultipart/form-data:

FieldRequiredNotes
statementyesPDF file, 25 MB max.
merchant_nameyesBusiness name.
mccno4-digit MCC. Inferred when omitted.
address, city, state, zipnoPhysical address. Blanks are backfilled from the statement.
dba_name, legal_name, phone, emailnoContact details for the lead.

Pass an Idempotency-Key header to make retries safe: the same key returns the proposal created the first time instead of making a duplicate.

The call is synchronous and can take 15–30 seconds while the statement is read. If the statement can’t be parsed you get a 422(the draft proposal is still created so the agent can retry in-app).

curl -X POST https://www.cygma.cloud/api/v1/proposals/analyze-statement \
  -H "Authorization: Bearer <your-key>" \
  -H "Idempotency-Key: 7f3c1b9e-…" \
  -F "statement=@statement.pdf;type=application/pdf" \
  -F "merchant_name=Jane's Coffee LLC" \
  -F "mcc=5812" \
  -F "address=123 Example St" \
  -F "city=Anytown" -F "state=ID" -F "zip=83702" \
  -F "email=owner@example.com"
GET /api/v1/applications

List applications

A paginated, read-only list of boarding applications. Requires the applications:read scope.

Query parameters:

  • page — 1-based page number (default 1).
  • page_size — items per page, max 100 (default 25).
  • status — filter by application status.
  • merchant_id — filter to one merchant.

The response envelope (data, page, page_size, total, has_more) is the same across every list endpoint.

curl "https://www.cygma.cloud/api/v1/applications?page=1&page_size=25&status=SUBMITTED" \
  -H "Authorization: Bearer <your-key>"
GET /api/v1/banking/routing/{routing}

Routing-number lookup

Resolve a 9-digit ABA routing number to its financial institution. Backed by EPI’s internal mirror of the Federal Reserve FedACH Participants Directory (refreshed monthly) — the same authoritative source the ISO360 and Merchant360 apps use, with no third-party dependency. Requires the banking:read scope.

Path parameter:

  • routing — the 9-digit ABA routing number (non-digits are stripped).

Responses: 422 if the number isn’t 9 digits or fails the ABA Mod-10 checksum; 404 if it passes the checksum but isn’t in the directory (a newer/smaller institution).

Try itsimulated example — no live call

GET /api/v1/banking/routing/121000248

This is a fixed sample. The live GET /api/v1/banking/routing/{routing} looks up any routing number — add Authorization: Bearer <your-key> and call it from your server.

curl "https://www.cygma.cloud/api/v1/banking/routing/121000248" \
  -H "Authorization: Bearer <your-key>"
GET /api/v1/banking/bin/{bin} — test data

Card BIN lookup

Identify a card from its leading digits. Alongside brand, credit / debit / prepaid, issuing bank, country, and the surcharge verdict, the response decodes the full card profile: the card indicator (e.g. H → “Debit hybrid — PIN and signature”), PIN / signature acceptance, the Durbin regulated-issuer flag, and the named debit networks the card routes on (with PINless capability). A credit card that also carries debit networks is flagged dual_routing. The product_id is decoded to a human-readable product tier in product_id_label (e.g. D → “Visa Signature Preferred”). Requires the banking:read scope.

Test data only. This endpoint serves a small static sample set — the well-known test BINs (411111, 555555, 371449, 601100, a debit, a prepaid, and a regulated example) — so you can build and exercise every response shape. It does not serve EPI’s production BIN directory; production lookups are available by agreement with Electronic Payments.

Path parameter:

  • bin — the first 6–16 digits of the card number (non-digits are stripped).

Responses: 200 with the card attributes; 422 if the BIN isn’t 6–16 digits; 404 for any BIN outside the sample set (the body lists the available samples).

Try itsimulated example — no live call, test data only

GET /api/v1/banking/bin/411111

These are fixed test BINs. The live endpoint serves the same sample set only; production BIN lookups are available by agreement with Electronic Payments.

curl "https://www.cygma.cloud/api/v1/banking/bin/486208" \
  -H "Authorization: Bearer <your-key>"
Success status codes

Responses

Successful responses return JSON with the resource under a data key. List endpoints add page, page_size, total, and has_more for pagination. The status code tells you what happened:

StatusMeaning
200OK — a read, lookup, or list succeeded; the resource is under data.
201Created — a new resource (e.g. a proposal from an analyzed statement) was created.
202Accepted — the request was queued for asynchronous processing.
// Reads + single-object responses wrap the object in `data`.
{ "data": { "id": "...", "...": "..." } }

// List endpoints wrap an array in `data` with pagination.
{ "data": [ { "...": "..." } ], "page": 1, "page_size": 25, "total": 42, "has_more": true }
HTTP status + { error }

Errors

StatusMeaning
401Missing, malformed, invalid, or revoked key.
403Key lacks the required scope (or isn’t office-bound).
413Statement file too large (25 MB max).
415Body isn’t multipart, or the file isn’t a PDF.
422Missing a required field, or the statement couldn’t be parsed.
429Rate limit exceeded — back off and retry.
// Errors return a JSON body with a single `error` string.
{ "error": "Missing required scope: proposals:create" }
Stability

Versioning

The API is versioned in the path (/api/v1). Within a version we only make backward-compatible changes: new fields are always optional, and we never remove or repurpose an existing field. A breaking change ships under a new version, and the old one keeps running through a deprecation window.

Build a tolerant client: ignore response fields you don’t recognize, and don’t depend on field order. That way new additions never break your integration.