Changelog
What changed on the public API surface and in the SDK packages, newest first.
This page lists changes to the public API surface and to the official SDK packages, newest first, one heading per day. API entries cover endpoints added or removed, request and response shapes, status codes, webhook events, scopes and rate-limit lanes, and are dated by the day the change reached the API. SDK entries are dated by the day the version reached its registry.
Every API entry below happened under the 2026-07-19 version stamp; a new
stamp would appear here as its own entry. How a request pins a stamp, and which
stamps are accepted, is on Versioning.
2026-09-05
@spreadspace/sdk0.3.0 (npm),spreadspace0.3.0 (PyPI) andSpreadSpace0.3.0 (NuGet) published. Notable changes since 0.1.8 (0.2.0 was never published on its own; its changes ship here):- Exports replace async operations. The async operations resource is gone
from all three packages.
client.exports(Exportsin C#) creates, reads, lists and cancels an export and waits on it, and adownloadLink/download_link/GetDownloadLinkAsyncread returns the bundle link with its expiry once the export has succeeded (anexport_not_readyerror before that). The create call’sdeliveryMode/delivery_modeparameter is gone. - Create requires
borrower_id,loan_idanddocument_ids, and the upload helpers require the loan id, so a request the server would answer with400no longer compiles or type-checks. export.succeeded,export.failed,export.cancelled,memo_render.succeeded,memo_render.failedandmemo_render.cancelledare in the typed event unions, with matching receiver handlers.- Typed attribute reads in Python (
AttributesEnvelope,AttributeVersions,AttributeSnapshot) and C# (GetAsync,VersionsAsyncandGetSnapshotAsyncreturn typed records, which changes their return types; the untyped reads remain asGetRawAsync,VersionsRawAsyncandGetSnapshotRawAsync). versions(loanId, status)filters the snapshot history to one status, anddeliveries(endpointId, ...)takesstatus,event_typeandloan_id.
- Exports replace async operations. The async operations resource is gone
from all three packages.
@spreadspace/react0.1.2 and@spreadspace/embed0.1.3 published (npm).
2026-09-04
- Six delete operations answer
204instead of200:DELETE /api/borrowers/{id},DELETE /api/loans/{id},DELETE /api/jobs/{jobId},DELETE /api/borrowers/{borrowerId}/extractions/{docId},DELETE /api/embed/sessions/{sessionId}andDELETE /api/webhooks/{id}. - Three create operations answer
201instead of200:POST /api/borrowers,POST /api/borrowers/{borrowerId}/loansandPOST /api/webhooks. 402is declared on every operation exceptGET /api/meandPOST /api/sandbox/reset. OnPOST /api/documents/presigned-url,POST /api/documents/presigned-urls-batch,POST /api/documents/{jobId}/confirm-upload,POST /api/documents/confirm-uploadsandPOST /api/intake, the402body’serroris one ofsubscription_required,spend_cap_reachedorinsufficient_credits, and a429can carry the flatusage_throttledbody with aRetry-Afterheader.- Fields that became required:
loan_idonPOST /api/documents/presigned-url;borrower_id,loan_idanddocument_idsonPOST /api/extractions/exports; theloanIdquery parameter onGETandPUT /api/borrowers/{borrowerId}/extractions/fin-ebitda-addbacks; theformatquery parameter (csvorjson) onGET /api/borrowers/{borrowerId}/extractions/{docId}/export, which also answers413doc_too_largefor a document over 10,000 line items. POST /api/borrowers/{borrowerId}/loans:borrower_idleft the request body; the path names the borrower.entity_keyon the rows ofGETandPUT /api/borrowers/{borrowerId}/extractions/fin-ebitda-addbacksis optional and nullable; it was required.- Response bodies are now declared for
GET /api/borrowers,GET /api/loans,GET /api/borrowers/{borrowerId}/loansandGET /api/webhooks(data,limit,next_cursor),GET /api/borrowers/{id}/jobs,GET /api/borrowers/{id}/jobs/{jobId}/results,GET /api/borrowers/{borrowerId}/extractions/query,POST /api/borrowers/{borrowerId}/extractions/query-bulkandPOST /api/sandbox/reset(reset,sandbox_tenant_present,reseeded,external_purge_errors). They were untyped on the reference before. POST /api/sandbox/resetacceptsIdempotency-Keyand declares409.POST /api/webhooks/{id}/rotatedeclares409again (rotating a revoked endpoint).- Every operation’s reference page now states the scope it requires and its
rate-limit lane:
api(200 requests per minute),upload(1000),export(120) orstrict(10, forPOST /api/sandbox/resetandPOST /api/webhooks/{id}/deliveries/{deliveryId}/replay). - The
keyingquery parameter leftGET /api/borrowers/{borrowerId}/extractions; it had no effect for an API key.
2026-09-02
GET /api/extractions/exports/{exportId}/downloadadded: answers302to a short-lived link for a succeeded export’s bundle, and404until the export has succeeded or once it has expired.- The export object took its final shape:
result_url,result_expires_atandresultare replaced bydownload_urlanddownload_expires_at, minted fresh on every read while the export is succeeded and unexpired;document_counts(requested,exported,skipped),skipped_document_idsandbundle(name,size_bytes,line_item_count) are new;linksgainsdownload. A cancel that lands on a running export moves it tocancelling, thencancelledat the next document boundary. - Six webhook events:
export.succeeded(the bundle is ready; fetch the export for a download link, the event never carries one),export.failed(reasonis the export’s error code),export.cancelled,memo_render.succeeded(pull the PDF through the memo’s own download endpoint),memo_render.failed(reasonis the render’s error code) andmemo_render.cancelled(a queued render was cancelled before it started). - A document’s company attachment carries
cross_kind(true when a Tax Return or Personal Financial Statement was filed by hand under an entity of the other kind), and extracted-document list items carryentity_unlinked(boolean).
2026-09-01
- Async operations were folded into the resources they served. Removed:
POST /api/async-operations/extraction_export,GET /api/async-operations,GET /api/async-operations/{operationId}andPOST /api/async-operations/{operationId}/cancel. Their replacements, in the Extractions group:POST /api/extractions/exports(answers202; a retry with the sameIdempotency-Keyreplays that response for 24 hours, after which the same key returns the existing export with200),GET /api/extractions/exports(its items key isexports),GET /api/extractions/exports/{exportId}andPOST /api/extractions/exports/{exportId}/cancel(409once the export has finished; an already-cancelled export is returned unchanged). The export object carriesexport_id,borrower_id,loan_id,format,status,progress,linksand its timestamps; there is nokindand nooperation_id. - Credit memo renders follow the same shape:
GET /api/loans/{loanId}/memos/{memoId}/renders/{renderId}andPOST /api/loans/{loanId}/memos/{memoId}/renders/{renderId}/canceladded, andPOST /api/loans/{loanId}/memos/{memoId}/rendersanswers202with the render (render_id,memo_id,loan_id,status,progress,links) instead of a generic operation. - Extracted-document list items carry
company_attachments, a list in the shape ofcompany_attachment.
2026-08-23
- Removed
GET /api/borrowers/{borrowerId}/extractions/financial-packetsandGET /api/borrowers/{borrowerId}/extractions/{docId}/financial-packet. A packet’s statements now arrive as separate Balance Sheet, Profit Loss Statement and Cash Flow Statement documents, read through their own list and retrieve operations, each carryingcpa_engagement. PUT /api/borrowers/{borrowerId}/extractions/fin-ebitda-addbackstakes anentityKeyquery parameter naming the company scope (business:orperson:followed by the folded name; omit it for the whole-loan scope), and add-back rows carryentity_key.
2026-08-22
- Added
GETandPUT /api/borrowers/{borrowerId}/extractions/fin-ebitda-addbacks: list and replace the saved EBITDA add-back selections for a loan (loanIdquery parameter).
2026-08-18
GET /api/loans/{loanId}/attributes/versionstakesstatus(final,machineordraft; any other value is400).GET /api/webhooks/{id}/deliveriestakesloan_id, and each delivery row carriesloan_id, the loan its event was about.xlsxexports are limited to Bank Statements: an export that names any other document type withxlsxis rejected with400(thenPOST /api/async-operations/extraction_export, nowPOST /api/extractions/exports).POST /api/sandbox/resetreturned to the public reference: a test-mode key restores its seeded workspace (sandbox:reset; a live key gets403mode_mismatch).GET /api/organizations/{id}left the reference;GET /api/organizationsandGET /api/meremain.@spreadspace/sdk,spreadspaceandSpreadSpace0.1.8 published (0.1.7 was never published on its own; its change ships here):loans.attributesreads (the latest snapshot of a status, the version history, and one snapshot by id), a webhook receiver that verifies the signature, drops redeliveries it has already processed, dispatches per event and reads the snapshot aspread.finalizednames,extraction.updated,spread.finalizedandspread.reopenedin the typed event unions, verifiers that accept several secrets for the rotation window, andexternal_user_idon the embed mint calls. In C#,ExtractionReadyPayloadandDocumentProcessedPayloadgained positional parameters, so code that constructs them positionally must re-check its arguments.
2026-08-17
- Added
GET /api/loans/{loanId}/attributes(the latest snapshot of a status),GET /api/loans/{loanId}/attributes/versions(the snapshot history) andGET /api/loans/{loanId}/attributes/{snapshotId}(one snapshot with its payload and manifest), underspreads:read. Snapshot reads carryfinalized_byandfinalized_by_external_user_id. - The webhook event catalog is part of the contract:
document.processed,document.failed,extraction.ready,extraction.updated,job.completed,loan.classifiedandspread.finalizedeach declare their envelope and payload;subscribed_eventsis typed to that list plus*; the delivery headersSpreadSpace-Signature,SpreadSpace-Event-IdandUser-Agent(SpreadSpace-Webhooks/1) are documented;GET /api/webhooks/{id}/deliveriesdeclares its page shape. - New event
spread.reopened: fires once per reopen of a finalized spread, naming thefinalsnapshot that stays in force until the nextspread.finalized. - Extracted-document list items carry
extraction_version.
2026-08-15
- Extracted-document list items carry
company_attachment: which of the borrower’s companies a financial document belongs to (entity_name,entity_ein_last4,printed_name), as resolved for that read, or null.
2026-08-14
POST /api/embed/sessionsanswers withpersistence:userwhen the mint carried anexternal_user_id(saved work comes back on that user’s next session),sessionwhen it did not.POST /api/embed/sessionsandPOST /api/embed/iframe-urlsacceptdisplay_name(requiresexternal_user_id; at most 120 characters; echoed in the response).
2026-08-13
- Typed retrieve and list pairs added under
/api/borrowers/{borrowerId}/extractions:balance-sheets,profit-loss-statements,cash-flow-statements,debt-schedules,ar-agingsandap-agings(lists), and{docId}/bank-statement,{docId}/ar-agingand{docId}/ap-aging(single documents). - Removed from the public surface, replaced by those pairs, all
GETunder/api/borrowers/{borrowerId}/extractions:pl,balance-sheet,accounts-receivable,accounts-payable,financial-statements,ar-aging-summariesand{docId}/ar-aging-summary.GET /api/borrowers/{borrowerId}/extractions/reports/{reportType}remains the read by category slug.
2026-08-12
- Added credit memo operations:
GET /api/loans/{loanId}/memos(the memos saved on a loan, with their render state),POST /api/loans/{loanId}/memos/{memoId}/renders(202; requests a PDF render) andGET /api/loans/{loanId}/memos/{memoId}/pdf(a short-lived link to the latest rendered PDF;404until a render has finished). - Removed from the public reference and the SDKs, as workspace and session
controls rather than server-to-server surface: the audit, compliance and
usage reads under
/api/borrowers/{id},/api/loans/{id}and/api/organizations/{id}; the analyst review controls under/api/borrowers/{borrowerId}/extractions;GET /api/loans/{loanId}/spreads(its successor is the attribute reads added 2026-08-17);PATCH /api/jobs/{jobId}/move;POST /api/embed/exchangeandPOST /api/embed/bootstrap-events.
2026-08-08
- Added
GET /api/borrowers/{borrowerId}/extractions/personal-financial-statements(list all Personal Financial Statements). POST /api/documents/{jobId}/confirm-uploadresponses carryduplicate_of_job_id(the prior job this upload duplicates; present only on aDUPLICATEstatus) andmessage.@spreadspace/sdk,spreadspaceandSpreadSpace0.1.6 published (0.1.5 was never published on its own; its change ships here): the webhooks resource calls/api/webhooks/*, and internal model types that had reached the generated packages are removed. Supersedes@spreadspace/sdk0.1.4 andspreadspace/SpreadSpace0.1.2.
2026-08-07
Idempotency-KeyleftPOST /api/webhooksandPOST /api/webhooks/{id}/rotate, along with the409they declared.- Extracted-document list items carry
entity_ein_last4. - The
/api/ui-stateoperations (on the reference since 2026-07-31) left the public reference: a session and embed surface that an API key cannot call.
2026-08-04
- The report template, report asset and dashboard operations
(
/api/report-templates,/api/report-assets,/api/me/tax-dashboards,/api/me/financial-dashboardsand/api/me/bank-dashboards) left the public reference: session-only surface that an API key cannot call.
2026-08-03
- Added
GET /api/borrowers/{borrowerId}/extractions/tax-returns(list all Tax Returns).GET /api/borrowers/{borrowerId}/extractions/financial-statementsandGET /api/borrowers/{borrowerId}/extractions/ar-aging-summarieswere added the same day and replaced on 2026-08-13.
2026-08-02
- Extracted-document list items carry
assurance_level, and borrower owner records (GET /api/borrowers/{borrowerId}/extractions/owners) carryaliases, the name variants seen.
2026-08-01
- Loans carry
guarantors, a list of guarantor names: onPOST /api/borrowers/{borrowerId}/loans, onPATCH /api/loans/{id}(omit the field to leave the list untouched, send a list to replace it, send an empty list to clear it) and in loan responses (null when none were declared or the caller may not read the loan file).
2026-07-31
POST /api/embed/sessionsandPOST /api/embed/iframe-urlsacceptexternal_user_id, an opaque, stable end-user id of at most 256 characters; the session response echoes it.- Added
GET /api/borrowers/{borrowerId}/extractions/{docId}/financial-packet(removed 2026-08-23).
2026-07-30
@spreadspace/sdk,spreadspaceandSpreadSpace0.1.2 published: release wiring only, no API surface change.@spreadspace/sdk0.1.3 (npm only): the API key is held in a private field so it cannot be read off the client by enumeration, serialization or a stray log.@spreadspace/sdk0.1.4 (npm only): republished with no source change.@spreadspace/react0.1.0 and 0.1.1, and@spreadspace/embed0.1.0, 0.1.1 and 0.1.2 published (npm), the first registry releases of the embed packages.
2026-07-23
- Added
GET /api/borrowers/{borrowerId}/extractions/{docId}/profit-loss-statement(retrieve a Profit Loss Statement). - Borrower owner records carry
k1_form.
2026-07-19
2026-07-19is the latest API version.2026-05-03is still accepted as a header value and resolves to the same behavior.- Added
GET /api/borrowers/{borrowerId}/extractions/{docId}/report-data: one document’s extraction payload whatever its category (the typed retrieve operations answer404outside their own type). POST /api/sandbox/resetandGET /api/borrowers/{borrowerId}/extractions/analysis-contextleft the public reference (the reset returned on 2026-08-18).