Integrations where every call carries the right token for the right API.
The integration that breaks at 2 a.m. is usually the one sharing an API key with three other jobs, right after someone rotated it. We work out authentication, retries and monitoring while we do the field mapping, not after it.
SalesforceMicrosoft Dynamics 365Microsoft Power PlatformSnowflake
in short·15-second read
API integration connects your systems so data moves between them reliably and securely.
Cohash designs and builds REST and event-driven integrations between CRM, ERP, data platforms and custom applications, including Salesforce and Dynamics 365. Each integration gets its own OAuth client, narrow scopes and audience-restricted tokens, checked against the OWASP API Security Top 10, with retries, idempotency and alerting so failures are visible.
you probably need this if
Integrations share one admin account and a password nobody wants to rotate.
A sync between the CRM and ERP fails quietly and someone notices days later.
The API trusts any signed-in caller. Swap the ID in the request and you get someone else's record back.
From the first call to a setup your own team can run.
Here's what usually prompts a call about your API Integration, what we do about it and in which order, and where you end up.
01 · where it hurts02 · what we change03 · how it runs04 · where you end up
incident board · api integration3 open
openIntegrations share one admin account and a password nobody wants to rotate.
recurringA sync between the CRM and ERP fails quietly and someone notices days later.
blockedThe API trusts any signed-in caller. Swap the ID in the request and you get someone else's record back.
exposure
Contract-first API designService-to-service authenticationObject-level authorizationEvent-driven integrationCRM and ERP connectionsGateways and observability
startrehearsehandover
Map flows and ownership
Design contracts and auth
Build and test failure cases
Operate
we are here
ready to hand over
Orders flow to the ERP as they change, and a failure alerts someone the same day.
Every route checks ownership and the tests prove it on each build.
Each change in Salesforce traces to one integration.
Integration inventory with system-of-record per field
chapter 01 · where it hurts
Why teams reach out
Integrations share one admin account and a password nobody wants to rotate.
A sync between the CRM and ERP fails quietly and someone notices days later.
The API trusts any signed-in caller. Swap the ID in the request and you get someone else's record back.
chapter 02 · what we change
How we solve it
Contract-first API design
Service-to-service authentication
Object-level authorization
Event-driven integration
CRM and ERP connections
Gateways and observability
chapter 03 · how it runs
Our approach
Map flows and ownership
Design contracts and auth
Build and test failure cases
Operate
chapter 04 · where you end up
What changes
Orders flow to the ERP as they change, and a failure alerts someone the same day.
Every route checks ownership and the tests prove it on each build.
Each change in Salesforce traces to one integration.
Integration inventory with system-of-record per field
what we do
Where we spend the hours
6 areas of work, each one done by an engineer who has run it in production.
We agree OpenAPI contracts before code, with a versioning policy, consistent pagination and error responses in the RFC 9457 problem details format.
We use OAuth 2.0 client credentials with one client per integration, and tokens are restricted to a single audience. Where the API supports it, tokens are bound to the caller with mTLS (RFC 8705) or DPoP (RFC 9449), following the OAuth security best practice in RFC 9700.
Broken object level authorization is the first risk in the OWASP API Security Top 10 2023. Every request is checked against who owns the record as well as whether the token is valid.
Queues and streams for work that can wait. Idempotency keys, dead-letter queues and replay mean we fix a failed message instead of losing it.
Salesforce and Dynamics 365 integrations designed around each platform's API limits and data model, with a named integration user per connection and permissions limited to the objects it touches.
Rate limits and authentication live at the API gateway, and tracing follows each request across hops. Alerts fire on error rates and queue depth, not on silence.
capability 01 / 06in production
Contract-first API design
We agree OpenAPI contracts before code, with a versioning policy, consistent pagination and error responses in the RFC 9457 problem details format.
We use OAuth 2.0 client credentials with one client per integration, and tokens are restricted to a single audience. Where the API supports it, tokens are bound to the caller with mTLS (RFC 8705) or DPoP (RFC 9449), following the OAuth security best practice in RFC 9700.
Broken object level authorization is the first risk in the OWASP API Security Top 10 2023. Every request is checked against who owns the record as well as whether the token is valid.
Salesforce and Dynamics 365 integrations designed around each platform's API limits and data model, with a named integration user per connection and permissions limited to the objects it touches.
Rate limits and authentication live at the API gateway, and tracing follows each request across hops. Alerts fire on error rates and queue depth, not on silence.
We pieced these together from API Integration situations that come up a lot. They're patterns. You won't find a specific client in them.
case file 01
Nightly CSV between Salesforce and the ERP that fails quietly
composite · not a client story
Beforethe situation
Orders move from Salesforce to the ERP through a nightly CSV export on an SFTP server. When a row fails, the job writes it to a log file nobody reads, and finance finds the gap at month-end.
What we dothe work
We replace the export with Salesforce Change Data Capture events feeding an integration service. Each message gets an idempotency key. Failures go to a dead-letter queue that raises an alert, and a small replay tool lets operations fix a message and send it again.
Afterwhere you end up
Orders flow to the ERP as they change, and a failure alerts someone the same day. Finance stops reconciling the two systems by hand at month-end.
case file 02
Partner API that returns any order when you change the ID
composite · not a client story
Beforethe situation
A partner-facing REST API validates the bearer token but not who owns the record. Changing the order ID in the path returns another partner's order, which a penetration test flagged as broken object level authorization.
What we dothe work
Add the ownership check in a shared authorization layer instead of per endpoint, and write tests that call every route with another partner's IDs. Issue each partner its own OAuth client with audience-restricted tokens, and log denied lookups for review.
Afterwhere you end up
Every route checks ownership and the tests prove it on each build. Attempts to read another partner's data show up in the logs instead of in the response.
case file 03
Eleven integrations signing in to Salesforce as one admin user
composite · not a client story
Beforethe situation
Eleven integrations sign in to Salesforce as one user with System Administrator and a password unchanged since go-live. Nobody can say which integration made a given change.
What we dothe work
We create one API-only integration user per integration, each with a permission set covering only the objects it touches. Each one moves to the OAuth client credentials or JWT bearer flow. Then the shared password gets rotated and retired.
Afterwhere you end up
Each change in Salesforce traces to one integration. Revoking one credential leaves the others running, and the audit trail finally answers who changed what.
How integrations authenticate and move data between systems
Each integration gets its own OAuth client and requests audience-restricted tokens from the identity provider. Calls pass through a gateway that checks scopes and records traffic, and events carry changes between CRM, ERP and the data platform.
How integrations authenticate and move data between systemsEach integration gets its own OAuth client and requests audience-restricted tokens from the identity provider. Calls pass through a gateway that checks scopes and records traffic, and events carry changes between CRM, ERP and the data platform.01 · CALLERS02 · CONTROL03 · SYSTEMSclient credentialsscoped tokenuser tokenAPI callRESTRESTchange eventsloadCustom applicationweb · mobile · batchIntegration serviceown OAuth clientAuthorization serverOkta · Entra ID ·Auth0API gatewayscopes · rate limits · logsEvent brokerKafka · Service Bus ·EventBridgeSfCRMSalesforceD365ERPDynamics 365Data platformSnowflake
01 · Callers
Custom applicationweb · mobile · batch → API gateway · user token
Integration serviceown OAuth client → Authorization server · client credentials→ API gateway · API call
02 · Control
Authorization serverOkta · Entra ID · Auth0 → Integration service · scoped token
Event brokerKafka · Service Bus · EventBridge → Data platform · load
03 · Systems
CRMSalesforce → Event broker · change events
ERPDynamics 365
Data platformSnowflake
Read the diagram as text
Integration service → Authorization server: client credentials
Authorization server → Integration service: scoped token
Custom application → API gateway: user token
Integration service → API gateway: API call
API gateway → CRM: REST
API gateway → ERP: REST
CRM → Event broker: change events
Event broker → Data platform: load
how it runs
A typical engagement
We don't start a step until the last one has produced something you can check.
step 01
Map flows and ownership
Settle which system owns each field and which way data moves. Then how fresh it has to be, and what happens when two systems disagree.
step 02
Design contracts and auth
API contracts, event schemas, OAuth clients, scopes and token lifetimes written down per integration.
step 03
Build and test failure cases
We test timeouts, duplicate messages, partial failures and expired tokens on purpose, before production finds them for us.
step 04
Operate
Dashboards, alerts and runbooks, plus a credential rotation schedule your team can run.
you keep
What you're left with
We write these for your API Integration setup, and they're working documents. Your team should be able to keep things running from them long after we've gone.
inventory01
Integration inventory with system-of-record per field
yours to keep
code02
OpenAPI specifications and event schemas
yours to keep
design03
Authentication design per integration covering client, scopes and token lifetime
Some clients want a project team, some want a couple of engineers on theirs. Either works. Onsite, nearshore or offshore, with handovers across time zones that keep things moving.
Onsite
Engineers at your sites in the US
Nearshore
Overlapping hours with US teams
Offshore
Overnight progress on your backlog
All time zones
Coverage handed over across time zones
24-hour coverage · US Central time
OnsiteUS business hours
Nearshoreoverlapping US hours
Offshoreovernight progress
Combinedhandover, not hand-off
00:0006:0012:0018:0000:00
roles we staff
Integration architect
API developer (REST, GraphQL)
Event streaming engineer (Kafka)
API security engineer (OAuth, OIDC)
Integration support engineer
due diligence · api integration
Questions to ask any partner, including us.
Put these to anyone bidding on your API Integration work. The ones who've done it answer differently from the ones who've read about it.
Q1
Which system owns each field, and what happens when both sides change it?
Most sync bugs are ownership disputes. A field-level owner and a conflict rule written down before build stop two systems overwriting each other in a loop.
Q2
How do retries avoid creating duplicate records?
Networks time out after the server has already done the work. Without idempotency keys, a retry creates a second order or a second payment.
Q3
How will you test object-level authorization on every endpoint?
Broken object level authorization tops the OWASP API Security Top 10 2023. It needs automated tests with another tenant's IDs on every build, not a single penetration test.
Q4
What happens to a failed message, and who is told?
A dead-letter queue nobody watches is the same as losing the message. Ask who gets alerted, how fast, and how a corrected message is replayed.
Q5
How will each credential be rotated without an outage?
A shared key breaks every integration when it rotates. Per-integration OAuth clients with overlapping secrets or certificates let you rotate one at a time.
01Should we use an integration platform or write custom code?
It depends on volume, the number of systems and your team. An iPaaS or Power Automate suits many standard connectors with modest volume. Custom services suit high volume, complex logic or strict latency. Many estates use both, and we draw the line explicitly.
02Are API keys good enough for internal integrations?
They work, but they're usually long-lived, shared and hard to scope. OAuth client credentials with short-lived, audience-restricted tokens give you per-integration revocation and an audit trail for the same effort.
03How do you avoid hitting Salesforce API limits?
We'd batch high-volume loads, subscribe to change events so nothing polls, and watch API consumption per integration user. What works best depends on your Salesforce edition and data volumes.
04Can you secure AI agents that call our APIs?
Yes. An agent should call your APIs with its own OAuth client and scoped, delegated tokens, the same discipline as any other integration. Our generative AI work covers this for agents and MCP servers.
05We already run MuleSoft or Azure Integration Services. Can you work inside it?
Yes. We follow the patterns your integration platform already uses and add the authentication, idempotency and monitoring design on top. If the platform you have does the job, we're not going to sell you a new one.
related
Often paired with
Projects on API Integration usually end up touching one of these, so they're worth a look.