Partner FX API
A purpose-built REST surface for UK payment firms, EMIs, and cross-border payment providers integrating AgentCredit into their CSM platform (Salesforce, HubSpot, custom). One call to onboard a client and get the recommended FX exposure limits; one call to record the dealer's accept / counter / reject decision; one call to read the full audit trail back.
Who this is for
Partner-FX endpoints are designed for service accounts running on behalf of a payment firm — not for end-user dashboards (use the standard REST API for that). Common integrations:
- Salesforce Apex / Flow that calls AC when a new FX trading client is created
- HubSpot workflow that scores a deal's primary contact's company
- Internal middleware (Node / Python) that hydrates client onboarding tickets
Each API key is owned by one AgentCredit account, plan-gated to the Team tier. One key per platform is fine; rotate via Settings → API keys.
Base URL
https://agentcredit.net/api/v1/partner/fx
Authentication
Every request carries a Bearer token in the Authorization header. Generate keys in Settings → API keys (the same key surface used for MCP).
Authorization: Bearer ack_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Keys are hashed at rest (SHA-256). The plaintext is shown only at creation; treat it like a password. Revoking a key takes effect on the next request — no cache.
Idempotency
Pass an Idempotency-Key header on every POST. Replays within 24 hours return the cached response; replaying the same key with a different request body returns 409 Conflict (Stripe-style semantics).
Idempotency-Key: 7f3a2b9c-1d4e-4a5f-9b8c-1234567890ab
Recommended: generate one UUID per CSM ticket / Salesforce record ID so retries (network jitter, queue redelivery) never double-create.
Endpoints
POST /partner/fx/onboard
One-shot: resolve the counterparty (by CRN or company name; live-fetches from Companies House if not on file), score them, derive the FX recommendation, and write an auto_suggested decision row to the audit trail. Returns grade + recommended limits.
Request
POST /api/v1/partner/fx/onboard
Authorization: Bearer <key>
Idempotency-Key: <uuid>
Content-Type: application/json
{
"company_number": "00445790", // optional, UK CRN (8 digits)
"company_name": "Atlas Engineering Ltd", // optional, fallback lookup
"financials": { ... }, // optional, inline financials
// if counterparty not on file
"requested_terms": { // optional, dealer's deal-specific
"notional": 5000000, // constraints; engine returns
"tenor_days": 180, // recommendation tailored to
"margin_call_pct": 0.05, // the request when present
"posted_collateral": 250000,
"initial_margin": 500000
}
}At least one of company_number, company_name, or financials is required.
Response · 200 OK
{
"borrower_id": "1cccc6be-ffe8-418c-ac7e-3af15a2ddbb9",
"company_name": "Atlas Engineering Ltd",
"company_number": "00445790",
"credit_grade": "B+",
"composite_pd": 0.018,
"fx_recommendation": {
"recommended_notional": 9000000.0,
"recommended_max_tenor_days": 270,
"margin_call_threshold_pct": 0.07,
"decision": "Enable",
"credit_grade": "B+",
"effective_notional": 5000000.0,
"posted_collateral": 250000,
"adverse_move_at_trigger": 350000.0,
"unsecured_exposure_at_trigger": 100000.0,
"collateral_coverage_ratio": 0.71,
"suggested_initial_margin": 350000.0,
"agreed_initial_margin": 500000.0,
"im_override_applied": true
},
"available_actions": ["accept", "counter_propose", "reject"],
"auto_suggested_decision_id": "bc40c70e-5a79-44d2-9789-505e21e28c52"
}POST /partner/fx/limits
Record the dealer's decision on the most recent auto-suggested recommendation. Creates or replaces the active FXClientLimit row on accept / counter; deactivates any active limit on reject. Frozen snapshot of the recommendation at decision time is preserved on the audit row regardless of subsequent recommendation drift.
Request
POST /api/v1/partner/fx/limits
Authorization: Bearer <key>
Idempotency-Key: <uuid>
Content-Type: application/json
{
"borrower_id": "1cccc6be-ffe8-418c-ac7e-3af15a2ddbb9",
"decision": "accept", // accept | counter_propose | reject
"terms": { // required for accept / counter
"notional": 5000000,
"tenor_days": 180,
"margin_call_pct": 0.05,
"initial_margin": 500000
},
"reason": "Standard terms, no overrides",
"decided_by_external_id": "sf-user-001" // CSM user identifier
}Response · 200 OK
{
"decision_id": "767f206b-ec6a-4980-bc5c-74c0e8259fbc",
"borrower_id": "1cccc6be-ffe8-418c-ac7e-3af15a2ddbb9",
"decision": "accept",
"limit_id": "2b8164b5-60dc-4473-9148-63dcf33e5d1c",
"status": "active", // active | rejected
"recorded_at": "2026-05-12T09:00:00Z"
}GET /partner/fx/limits/{borrower_ref}
Current active limit + the live recommendation (which may have drifted since the limit was set, e.g. grade dropped after a new filing) + full decision history (most recent 50 rows). Accepts either an AC borrower_id (UUID) or a UK CRN (8 digits).
Response · 200 OK
{
"borrower_id": "1cccc6be-ffe8-418c-ac7e-3af15a2ddbb9",
"company_name": "Atlas Engineering Ltd",
"company_number": "00445790",
"current_grade": "B+",
"current_limit": {
"limit_id": "2b8164b5-60dc-4473-9148-63dcf33e5d1c",
"notional": 5000000.0,
"tenor_days": 180,
"margin_call_pct": 0.05,
"approved_at": "2026-05-12T09:00:00Z"
},
"current_recommendation": { ... }, // recomputed live
"decisions": [
{
"decision_id": "767f206b-...",
"decision_type": "accept",
"terms": { ... },
"recommendation_at_decision": { ... }, // frozen
"reason": "Standard terms",
"decided_by_external_id": "sf-user-001",
"activated_limit_id": "2b8164b5-...",
"decided_at": "2026-05-12T09:00:00Z"
},
{
"decision_id": "bc40c70e-...",
"decision_type": "auto_suggested",
...
}
]
}Use this to detect recommendation drift — if current_recommendation.recommended_notional no longer matches the active current_limit.notional, the counterparty's credit picture has changed since you set the limit. Surface that diff to the dealer in your CSM UI.
Error codes
| Status | Cause | Action |
|---|---|---|
400 | Required field missing | Inspect detail in body |
401 | Missing / invalid / revoked Bearer token | Check the key, generate a new one |
403 | Key's owner is not on a paid plan | Upgrade at /pricing |
404 | Counterparty not found and no financials supplied | Upload via /api/v1/financials/upload first |
409 | Idempotency-Key reused with different body | Use a new key or send identical body |
5xx | Scoring engine error | Safe to retry with same Idempotency-Key |
End-to-end example (curl)
# 1. Onboard
curl -X POST https://agentcredit.net/api/v1/partner/fx/onboard \
-H "Authorization: Bearer $KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"company_number":"00445790","requested_terms":{"notional":5000000,"tenor_days":180}}'
# 2. Accept the suggested terms
curl -X POST https://agentcredit.net/api/v1/partner/fx/limits \
-H "Authorization: Bearer $KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"borrower_id":"<id from step 1>",
"decision":"accept",
"terms":{"notional":5000000,"tenor_days":180,"margin_call_pct":0.07,"initial_margin":350000},
"decided_by_external_id":"sf-user-001"
}'
# 3. Read history later (e.g. nightly drift check)
curl https://agentcredit.net/api/v1/partner/fx/limits/00445790 \
-H "Authorization: Bearer $KEY"Rate limits & SLA
- Per-key: 10 requests / second sustained, burst 20 / second
- Idempotency cache: 24 hours per key + body hash
- On-demand CH ingest (used when CRN is not in our DB): adds 2-6 seconds to the onboard call. Subsequent onboards for the same CRN are instant.
For production CSM integrations, run the onboard call asynchronously from your write path — don't block a Salesforce / HubSpot user on the AC round-trip.
Need help integrating?
Partner integrations get bespoke onboarding. Email [email protected] with your platform (Salesforce / HubSpot / custom) and we'll set up a sandbox account, share Postman / Insomnia collection, and review the integration before you go live.