Introducing SpreadSpace Markets, our new market research workspace. Starting at $129/mo per seat. Floor volume discounts

API security

Financial spreading API security compared with Ocrolus

How the SpreadSpace API secures connections, retries and webhooks, compared with Ocrolus and set against the security hygiene of Stripe and Plaid.

By Zach Tahajian

A financial spreading API carries a borrower’s tax returns, bank statements and financial statements between two companies’ systems. It reads documents and returns spreads. It does not move money like Stripe or pull data out of bank accounts like Plaid, and an API that does either answers to a stricter standard. The fair bar for a spreading API is another API that reads lending documents, so this guide uses Ocrolus as that bar and treats Stripe and Plaid as the security hygiene above it.

A security review can check three protocols at the level of each request. Every connection should run over TLS 1.2 or later, every call that changes data should accept an idempotency key so a retry never runs twice, and every webhook should carry an HMAC-SHA256 signature over a timestamp and the body.

The SpreadSpace API runs all three. Ocrolus’s API runs TLS and offers signed webhooks, and its documentation names no idempotency key. This guide sets the two side by side on each protocol, from Ocrolus’s published documentation and a TLS handshake test we ran against each production API host on November 3, 2026, then sets SpreadSpace beside Stripe and Plaid and reports what other spreading vendors document.

Three protocols and what each one stops

Each protocol closes a specific failure. TLS keeps a request private and unaltered on the wire. An idempotency key turns a retry after a timeout into a safe operation rather than a second upload or a second export. A webhook signature lets the lender’s system prove that an event came from the vendor and was not changed on the way.

The protocols and how SpreadSpace applies each one
ProtocolWhat it stopsHow SpreadSpace applies it
TLS 1.3 and TLS 1.2Reading or altering a request in transit, and downgrades to older protocol versionsThe API host refuses TLS 1.0 and 1.1 and every cipher suite without forward secrecy
Idempotency keysA retried request creating a second upload, export or recordAn Idempotency-Key header on a POST, PUT, PATCH or DELETE call replays the first response for 24 hours
Request fingerprintA reused key quietly applying to a different requestThe method, path and body are fingerprinted with the key, and a mismatch is refused
Signed webhooksA forged or altered event reaching the lender’s systemEvery delivery carries an HMAC-SHA256 signature over a timestamp and the raw body
Replay windowA captured delivery being sent again laterThe official SDKs refuse a signature whose timestamp sits more than five minutes from the receiver’s clock
Secret rotationA secret change dropping deliveriesThe previous webhook secret stays valid beside the new one for 24 hours

None of the three is exotic. Stripe documents all of them, and an engineering team that has integrated payments already knows how to use them. What a lender should check is whether a spreading vendor documents them, applies them to every call that changes data, and holds its production host to the TLS versions it states.

SpreadSpace API security and compliance

SpreadSpace and Ocrolus on each protocol

Ocrolus is the closest comparison, because its API reads bank statements and other lending documents for lenders, as SpreadSpace does. On transport the two production hosts returned the same result. Each accepted TLS 1.3 and TLS 1.2, refused TLS 1.1 and TLS 1.0, accepted only TLS 1.2 cipher suites with forward secrecy and sent a Strict-Transport-Security header for a year. For webhooks both use HMAC-SHA256 over a timestamp and the body, and Ocrolus adds a request id to what it signs.

SpreadSpace and Ocrolus on each protocol, from Ocrolus’s documentation and our handshake test on November 3, 2026
ProtocolSpreadSpaceOcrolus
TLS versionsTLS 1.3 and TLS 1.2TLS 1.3 and TLS 1.2
TLS 1.2 suites without forward secrecyRefusedRefused
Idempotency keysAn Idempotency-Key header on every call that changes data, honored for 24 hoursNot documented
Webhook signaturesOn every delivery, with no setting to turn them offOpt-in
Webhook secretGenerated by SpreadSpace from 192 random bits and shown onceGenerated and registered by the customer, 16 to 128 characters
What the signature coversA timestamp and the raw bodyA timestamp, a request id and the body
Replay windowFive minutes, enforced by the official SDKsNot documented

The differences start with what a customer has to set up. Ocrolus lists its webhook signature, its IP allowlist and HTTP basic authentication as opt-in methods, so an endpoint registered without them receives deliveries it has no way to check. SpreadSpace signs every delivery, and no setting turns the signature off. Ocrolus asks each customer to generate a secret of 16 to 128 characters and register it through its API, while SpreadSpace generates each endpoint’s secret from 192 random bits and shows it once. Ocrolus documents no limit on the age of the timestamp it signs, and the official SpreadSpace SDKs refuse a delivery whose timestamp sits more than five minutes from the receiver’s clock.

The widest gap is the protocol Ocrolus does not document. Its API reference, read page by page, names no idempotency key, so when a create call times out an Ocrolus integration has to work out on its own whether the call ran before it tries again. SpreadSpace replays the first response to a retried call that carries the same key for 24 hours, and its SDKs attach the key without any code from the integration.

Ocrolus webhook security methods

Ocrolus webhook secret configuration

TLS measured on the production API hosts

TLS protects a request on the wire, and the versions and cipher suites a host accepts decide how strong that protection is. A connection to api.spreadspace.app negotiates TLS 1.3 or TLS 1.2. Earlier versions are refused, and so is every TLS 1.2 cipher suite whose key exchange lacks forward secrecy, so a recording of today’s traffic cannot be decrypted later with a stolen server key.

TLS handshakes against each production API host on November 3, 2026
Handshake offeredSpreadSpaceOcrolusStripePlaid
TLS 1.3AcceptedAcceptedAcceptedRefused
TLS 1.2AcceptedAcceptedAcceptedAccepted
TLS 1.1 and TLS 1.0RefusedRefusedRefusedRefused
TLS 1.2 suites without forward secrecyRefusedRefusedAcceptedRefused

Anyone can repeat the test. We opened a handshake at each TLS version against api.spreadspace.app, api.ocrolus.com, api.stripe.com and production.plaid.com, then offered each host the TLS 1.2 cipher suites one at a time. SpreadSpace, Ocrolus and Stripe accepted TLS 1.3 and TLS 1.2, and Plaid’s production host accepted TLS 1.2 and refused TLS 1.3. Of the 155 TLS 1.2 suites offered, Stripe’s host accepted four with RSA key exchange, which carry no forward secrecy, while every suite that the other three hosts accepted carries it.

Every hop behind the security edge is encrypted as well, up to the service that answers the request, and the API sends a Strict-Transport-Security header that tells browsers to use HTTPS for a year. Browsers also ship with a preload list of domains they reach only over HTTPS, and every .app domain is on it, spreadspace.app included, so a browser never opens a plain HTTP connection to a SpreadSpace host, even on a first visit. Stripe and Plaid have their own domains on the same list, and ocrolus.com is not on it. Webhook deliveries travel the other way over HTTPS only, and an endpoint registered with a plain http address is refused at registration.

Stripe integration security guide

Mozilla server side TLS recommendations

HSTS preload list status for spreadspace.app

Idempotency keys and safe retries

A network error leaves a client unsure whether its request ran. Without an idempotency key, a retry can create a second export or a second upload, and the integration has to list what exists before it can safely try again. Stripe answered this with an Idempotency-Key header, and SpreadSpace accepts the same header on every POST, PUT, PATCH and DELETE call made with an API key.

Idempotency keys as each API documents them
BehaviorSpreadSpaceStripePlaid
Where the key goesIdempotency-Key headerIdempotency-Key headeridempotency_key field in the request body
Calls that accept itEvery POST, PUT, PATCH and DELETE made with an API keyEvery POST in API v1Transfer requests such as authorizations
Longest key255 characters255 characters50 characters
How long a key is honored24 hoursAt least 24 hours48 hours on an authorization
Key reused for a different requestRefused with 409 idempotency_request_mismatchRefused with an errorNot documented
Duplicate sent while the first is runningWaits up to 30 seconds and replays the first responseNot stored, and the client retriesNot documented
Server errorsReplayed, except a 429 or 503 that asks for a retryReplayed, including 500 errorsNot documented

SpreadSpace stores each response under the API key that sent it, so two credentials never share an entry, and it checks the caller’s current scopes before it replays anything, so a replay never returns what the key can no longer read. The official TypeScript, Python and C# SDKs generate a key for every call that changes data and reuse it on their own retries, so an integration has the protection without writing code for it.

Plaid documents its key as a field in the body of its transfer requests, such as a transfer authorization, where a duplicate could charge an account twice.

Idempotency in the SpreadSpace API documentation

Stripe idempotent requests

Plaid transfer authorization reference

Signed webhooks and replay protection

A webhook is a request the lender’s system did not ask for, which makes it the easiest request to forge. SpreadSpace signs every delivery with the scheme Stripe uses. The SpreadSpace-Signature header carries a timestamp and an HMAC-SHA256 of the timestamp joined to the raw body, keyed with the endpoint’s own secret, so a changed byte or an old timestamp fails verification.

Webhook signatures as each API documents them
BehaviorSpreadSpaceStripePlaid
SignatureHMAC-SHA256HMAC-SHA256ES256 JSON Web Token
What the signature coversA timestamp and the raw bodyA timestamp and the raw bodyThe issue time and a SHA-256 hash of the raw body
HeaderSpreadSpace-SignatureStripe-SignaturePlaid-Verification
Default replay windowFive minutes either side of the receiver’s clockFive minutesFive minutes from issue
RotationThe previous secret stays valid beside the new one for 24 hoursThe previous secret can stay valid for up to 24 hoursKeys roll over by key id

Plaid reaches the same guarantee by another route. Its Plaid-Verification header holds a JSON Web Token signed with ES256, a public-key signature, and the token carries a SHA-256 hash of the body. A public key spares the receiver from storing a shared secret, and a per-endpoint HMAC secret spares it a key fetch and a token library. Both tie the signature to the exact body and to a five-minute window, which is the property that matters.

Each SpreadSpace delivery also names its event in a SpreadSpace-Event-Id header that stays the same across every retry and replay, so a receiver can drop duplicates. Deliveries go only to HTTPS endpoints, never follow a redirect, and leave from one published address for receivers that allowlist by source IP. The official SDKs compare signatures in constant time and hand the handler a parsed event only after the signature passes.

Webhooks in the SpreadSpace API documentation

Stripe webhook signature verification

Plaid webhook verification

Keys, scopes and isolation

The protocols protect each request, and the credential behind it decides what a stolen key could reach. A SpreadSpace API key is shown once, at creation, and stored only as a salted hash. Each key carries an explicit set of scopes, and its prefix names its mode. A key that starts with ss_test_ reads an isolated sandbox and can never read live data, the same separation Stripe draws between its test and live keys.

Every record belongs to one organization. A request that names a record in another organization answers 404, the same as a record that does not exist, so an id never reveals what exists elsewhere. A rotated key stays valid for a grace period chosen at rotation, 24 hours by default, so a deploy can move to the new key without a gap. Per-client rate limits and a web application firewall stand in front of the API, and API events are logged with up to seven years of retention.

Authentication in the SpreadSpace API documentation

SpreadSpace trust and reliability

What other spreading vendors document

On November 2, 2026 we read the public API documentation of the spreading and lending document vendors that publish one. None of them documents idempotency keys, so none documents all three protocols, and a retried upload or export is left for each integration to reconcile. Five of the six sign their webhooks with HMAC-SHA256, the algorithm SpreadSpace and Stripe use, but only Ocrolus includes a timestamp in what it signs. A signature over the body alone still verifies when a captured delivery is sent again a day later.

Idempotency keys and webhook authentication in each vendor’s public documentation on November 2, 2026
VendorIdempotency keysWebhook authentication
SpreadSpaceAn Idempotency-Key header on every call that changes data, honored for 24 hoursHMAC-SHA256 over a timestamp and the raw body
OcrolusNot documentedHMAC-SHA256 over a timestamp, a request id and the body
Heron DataNot documentedHMAC-SHA256 over the body, without a timestamp
InscribeNot documentedHMAC-SHA256 over the body, without a timestamp
UPTIQ Document AINot documentedHMAC-SHA256 over the body, without a timestamp
nCino eVault and mortgage APIsNot documentedHMAC-SHA256 over the body, without a timestamp
AbrigoNot documentedThe webhook’s secret key itself, sent in a header

nCino’s spreading runs inside its banking platform, and the business banking documentation on its developer portal requires a customer login, so the table shows the eVault and mortgage APIs it documents in public. Several other spreading vendors publish no API reference at all, and for them the questions in the next section are the only way to learn the answers. A vendor may also run protections it does not document, which is one more reason to test the production host and ask.

Ocrolus webhook signature verification

Heron Data webhooks

Inscribe webhooks

UPTIQ Document AI webhook payloads

nCino eVault webhooks

nCino Mortgage webhooks

Abrigo webhook request format

What to ask a spreading API vendor

Ask for the production API host and test it yourself. A handshake at each TLS version needs only standard tools, and the result is a fact rather than a questionnaire answer. Then ask what happens when a create call times out and the client sends it again. When the answer is that the client should list what exists and decide, the vendor has no idempotency keys, and every integration has to build that reconciliation on its own.

Ask how a webhook proves where it came from. A shared key in a header proves little, because anyone who sees one delivery holds the key and can send any payload with it, and an IP allowlist only says which network sent the request. A signature over a timestamp and the body is the standard Stripe and Plaid both meet, and it is the one to require. Ask too whether every delivery carries the signature or only deliveries to an endpoint the customer has configured, and who generates the secret.