Skip to Content
Reporting APIReport Endpoints

Report Endpoints

Endpoints for drafting regulatory reports from Orca data and reading them back.

Reports created through these endpoints are drafts. They are autopopulated from the data you send and placed in the approval queue in the Orca dashboard. Filing with the Financial Intelligence Centre happens only from the dashboard, on an explicit action by your reporting officer. See Introduction for the full flow.

Create Report

Draft a single report. Orca populates the goAML report structure from the subject, transactions and merchant you reference, plus your client configuration, and returns the draft’s identifier.

Endpoint

POST /v1/report

Request Schema

FieldTypeRequiredDescription
reportTypeenumYesReport type: STR, SAR, CTR, IFTR, Other
idstringNoYour own identifier for this report. Used for idempotency, repeating a request with the same id returns the existing draft rather than creating a second one. Orca generates one if omitted
reportNumberstringNoYour internal report or case number, carried onto the filing
titlestringNoShort report title. Autopopulated from the template or from the subject and trigger if omitted
descriptionstringNoOne-line summary of the report
reasonstringNoGrounds for the report, the narrative that becomes the goAML transaction description and report reason. Autopopulated from the template if omitted
actionstringNoAction taken by your institution (for example the resulting account status). Autopopulated from the template if omitted
templateIdstringNoIdentifier of a report template configured for your client. Populates title, reason and action, with any field you send taking precedence
indicatorsarrayNogoAML reporting indicator codes, for example ["RIND124"]. Your reviewer can add or remove these in the dashboard
caseOpenedAtnumberNoUnix epoch milliseconds, when the underlying case or alert was opened
timestampnumberNoUnix epoch milliseconds. Defaults to receipt time
userIdstringConditionalIdentifier of the report subject. Omit if user is used. See Subject or transaction is required
userobjectConditionalComplete User object. Omit if userId is used. Use this if the subject was not previously sent to /v1/user. See Subject or transaction is required
transactionIdsarrayConditionalIdentifiers of transactions to include. Omit if transactions is used. See Subject or transaction is required
transactionsarrayConditionalArray of complete Transaction objects. Omit if transactionIds is used. Use this if the transactions were not previously sent to /v1/transaction. See Subject or transaction is required
merchantIdstringNoIdentifier of the merchant party, where the report concerns a merchant. Omit if merchant is used
merchantobjectNoComplete Merchant object. Omit if merchantId is used

Referencing subjects and transactions

Every entity on a report can be supplied either by identifier, if you have already sent it to Orca, or inline as a full object, if you have not. Reuse the same user, transaction and merchant objects you already use elsewhere in the API; no reporting-specific shape is needed:

You haveSendResult
Already called /v1/useruserIdOrca reads the stored user, including KYC, AML, salary and document detail
Not called /v1/useruserOrca creates or updates the user, then populates from it
Already called /v1/transactiontransactionIdsOrca reads the stored transactions, including their triggered rules
Not called /v1/transactiontransactionsOrca stores the transactions, then populates from them
A merchant party is involvedmerchantId or merchantMerchant becomes the counterparty on the filing

Subject or transaction is required

A report needs something to be about. At least one of a subject or a transaction must be on the request — that is, at least one of userId, user, transactionIds or transactions. A request carrying none of them is rejected with a VALIDATION_ERROR and no draft is created.

Either group on its own is enough:

SentAcceptedNotes
userId or userYesSubject-only report. Normal for a SAR, where there may be no concluded transaction
transactionIds or transactionsYesTransaction-only report. Orca resolves the subject from the transactions where they carry one
BothYesThe usual call, and the most completely autopopulated
NeitherNoVALIDATION_ERROR, 400

merchantId and merchant do not satisfy this on their own — a merchant is a counterparty on the filing, not the report subject.

{ "error": { "type": "VALIDATION_ERROR", "message": "Request validation failed", "details": [ "/: at least one of `userId`, `user`, `transactionIds` or `transactions` is required" ] }, "timestamp": 1754006400123 }

Everything else on the request is optional. In practice userId plus transactionIds is the normal call.

What Orca populates for you

You do not send goAML fields. Orca derives them:

goAML areaDerived from
Report header: schema version, report date, report typeRequest plus receipt time
Reporting entity: rentityId, entity name, branch, registration numberYour client configuration
Reporting person and reporting locationYour client configuration and the submitting dashboard user
Transaction: number, amount, currency, transmission mode, date, descriptionThe referenced transaction objects
t_from / t_to parties: person, identity document, address, phone, occupation, employerThe referenced user and merchant objects
Account block: account number, type, institution, status, currency, balanceThe referenced transaction and user objects
Indicators, reason, actionThe request, or the report template

Anything Orca cannot derive is left blank for your reviewer rather than guessed at.

Example Request

{ "reportType": "STR", "reportNumber": "CASE-2026-00841", "title": "STR: Deposits disproportionate to declared income", "description": "High movement of deposits against declared monthly income", "reason": "Subject completed deposits totalling ZAR 1 240 000 over 30 days against a declared monthly income of ZAR 28 000. Deposits originate from three unrelated banks and are not withdrawn.", "action": "Account Status: Active. Subject to be reported for an STR due to high movement of deposits.", "indicators": ["RIND002", "RIND049", "RIND124"], "userId": "USER123", "transactionIds": ["TXN123", "TXN124", "TXN125"], "caseOpenedAt": 1753900000000, "timestamp": 1754006400000 }

Example Request: inline objects

Use this form when the subject and transactions have not been sent to Orca separately.

{ "reportType": "SAR", "reason": "Attempted deposit declined on KYC mismatch; subject reattempted with altered identity detail.", "indicators": ["RIND037"], "user": { "id": "USER456", "firstName": "John", "lastName": "Doe", "dateOfBirth": "1990-01-01", "phone": { "phone": "+27821234567", "country": "ZA", "isVerified": true }, "kycDetail": { "kycStatus": "FAILED", "sourceOfIncome": "self-employed" }, "status": "BLOCKED" }, "transactions": [ { "id": "TXN789", "userId": "USER456", "status": "DECLINED", "currencyCode": "ZAR", "amount": 85000, "direction": "payin", "actionType": "deposit", "paymentMethod": "bank", "timestamp": 1754006400000 } ] }

Response Schema

FieldTypeDescription
reportIdstringOrca identifier for the created draft
statusstringAlways draft for reports created over the API
reportTypestringReport type as recorded
reportNumberstringYour internal report number, if supplied
fiuReferenceNumberstringFIC reference number. null until the report is filed from the dashboard
createdAtnumberUnix epoch milliseconds
requiresReviewbooleanAlways true, the draft awaits human approval before it can be filed
populatedobjectSummary of what Orca autopopulated
populated.userbooleanWhether a subject was resolved and populated
populated.merchantbooleanWhether a merchant party was resolved and populated
populated.transactionsnumberNumber of transactions attached to the report
populated.indicatorsnumberNumber of indicator codes recorded
incompletearrayFields the reviewer must supply before the report can be filed

Example Response

{ "reportId": "rep_01JQ4T8ZC7K2XN", "status": "draft", "reportType": "STR", "reportNumber": "CASE-2026-00841", "fiuReferenceNumber": null, "createdAt": 1754006400123, "requiresReview": true, "populated": { "user": true, "merchant": false, "transactions": 3, "indicators": 3 }, "incomplete": [], "timestamp": 1754006400123 }

A draft with gaps returns them so you know what the reviewer will be asked for:

{ "reportId": "rep_01JQ4T9M18F0PB", "status": "draft", "reportType": "STR", "fiuReferenceNumber": null, "createdAt": 1754006400456, "requiresReview": true, "populated": { "user": true, "merchant": false, "transactions": 1, "indicators": 0 }, "incomplete": [ "indicators", "user.documents", "user.address" ], "timestamp": 1754006400456 }

Responses

  • 200: Report draft created
  • 400: Bad request, including a request with no userId, user, transactionIds or transactions. See Error Reference
  • 401: Unauthorized
  • 403: Reporting not enabled for this client
  • 404: A referenced userId, transactionIds entry or merchantId was not found
  • 500: Internal server error

Create Reports in Bulk

Draft many reports in one request. Each item is validated and populated independently, so a bad item does not discard the good ones. Use this for periodic compliance sweeps and backfills rather than for real-time reporting.

Endpoint

POST /v1/reports/bulk

Request Schema

FieldTypeRequiredDescription
reportsarrayYesArray of report objects. Each entry uses exactly the Create Report request schema, and each must satisfy Subject or transaction is required on its own

The default maximum batch size is 100 reports per request. Contact support@orca-fraud.com if you need a higher limit.

Example Request

{ "reports": [ { "id": "CASE-2026-00841", "reportType": "STR", "reason": "Deposits disproportionate to declared income.", "indicators": ["RIND002", "RIND124"], "userId": "USER123", "transactionIds": ["TXN123", "TXN124"] }, { "id": "CASE-2026-00842", "reportType": "STR", "reason": "Repeated transfers between linked accounts with no economic purpose.", "indicators": ["RIND104"], "userId": "USER456", "transactionIds": ["TXN501"] }, { "id": "CASE-2026-00843", "reportType": "CTR", "userId": "USER789", "transactionIds": ["TXN903"] }, { "id": "CASE-2026-00844", "reportType": "Other", "reason": "Merchant flagged during periodic review.", "merchantId": "MERCH123456" } ] }

Response Schema

FieldTypeDescription
createdarrayReports drafted successfully
created[].indexnumberZero-based position of the item in the request reports array
created[].idstringYour own identifier for the item, if supplied
created[].reportIdstringOrca identifier for the created draft
created[].statusstringAlways draft
created[].populatedobjectSame shape as the single-report populated object
created[].incompletearrayFields the reviewer must supply
failedarrayItems that were rejected
failed[].indexnumberZero-based position of the rejected item
failed[].idstringYour own identifier for the item, if supplied
failed[].errorobjectError object in the standard error format
summary.receivednumberItems in the request
summary.creatednumberDrafts created
summary.failednumberItems rejected

An item with no userId, user, transactionIds or transactions fails on its own with a VALIDATION_ERROR and does not affect the rest of the batch.

Items in created are queued for review regardless of what is in failed. Retry only the failed items, resending a successful item with the same id returns the existing draft rather than creating a duplicate.

Example Response

{ "created": [ { "index": 0, "id": "CASE-2026-00841", "reportId": "rep_01JQ4T8ZC7K2XN", "status": "draft", "populated": { "user": true, "merchant": false, "transactions": 2, "indicators": 2 }, "incomplete": [] }, { "index": 1, "id": "CASE-2026-00842", "reportId": "rep_01JQ4T8ZC7K3PA", "status": "draft", "populated": { "user": true, "merchant": false, "transactions": 1, "indicators": 1 }, "incomplete": ["user.documents"] } ], "failed": [ { "index": 2, "id": "CASE-2026-00843", "error": { "type": "NOT_FOUND", "message": "Transaction not found", "details": ["/transactionIds/0: TXN903 does not exist"] } }, { "index": 3, "id": "CASE-2026-00844", "error": { "type": "VALIDATION_ERROR", "message": "Request validation failed", "details": [ "/: at least one of `userId`, `user`, `transactionIds` or `transactions` is required" ] } } ], "summary": { "received": 4, "created": 2, "failed": 2 }, "timestamp": 1754006400789 }

Responses

  • 200: Batch processed - inspect created and failed for per-item outcomes
  • 400: Bad request - the envelope itself was invalid, for example reports missing or over the batch limit. No drafts were created
  • 401: Unauthorized
  • 403: Reporting not enabled for this client
  • 429: Too many requests
  • 500: Internal server error

Get Report

Retrieve a single report, including the goAML content Orca has populated and the report’s audit trail.

Endpoint

GET /v1/reports/{reportId}

Path Parameters

ParameterTypeRequiredDescription
reportIdstringYesOrca identifier of the report

Query Parameters

ParameterTypeRequiredDescription
includestringNoComma-separated extras to embed: content for the populated goAML content, audit for the change history. Default: neither

Response Schema

FieldTypeDescription
idstringOrca report identifier
statusenumdraft, pending_review, submitted, rejected, resubmission_required, amended, archived
reportTypeenumSTR, SAR, CTR, IFTR, Other
reportNumberstringYour internal report number
fiuReferenceNumberstringFIC reference number, once filed
titlestringReport title
descriptionstringReport summary
reasonstringGrounds for the report
templateIdstringTemplate used, if any
indicatorsarraygoAML indicator codes recorded on the report
userIdstringReport subject
transactionIdsarrayTransactions attached to the report
caseOpenedAtnumberWhen the underlying case was opened
createdAtnumberCreation timestamp
createdByIdstringWho created the report. api for reports created over this API
updatedAtnumberLast update timestamp
updatedByIdstringWho last updated the report
submittedAtnumberWhen the report was filed with the FIC
submittedByIdstringDashboard user who filed the report
contentobjectPopulated goAML content. Read-only, and present only with include=content
auditarrayChange history. Present only with include=audit

content mirrors the goAML report structure, reporting entity, reporting person, reporting location, transaction with its t_from and t_to parties, account, indicators, reason and action. It is generated by Orca and cannot be written through the API; the dashboard is the only place it can be edited.

Example Response

{ "id": "rep_01JQ4T8ZC7K2XN", "status": "pending_review", "reportType": "STR", "reportNumber": "CASE-2026-00841", "fiuReferenceNumber": null, "title": "STR: Deposits disproportionate to declared income", "description": "High movement of deposits against declared monthly income", "reason": "Subject completed deposits totalling ZAR 1 240 000 over 30 days against a declared monthly income of ZAR 28 000.", "templateId": null, "indicators": ["RIND002", "RIND049", "RIND124"], "userId": "USER123", "transactionIds": ["TXN123", "TXN124", "TXN125"], "caseOpenedAt": 1753900000000, "createdAt": 1754006400123, "createdById": "api", "updatedAt": 1754010000000, "updatedById": "EMP-2841", "submittedAt": null, "submittedById": null, "timestamp": 1754010500000 }

Responses

  • 200: Report returned
  • 401: Unauthorized
  • 403: Reporting not enabled for this client
  • 404: Report not found
  • 500: Internal server error

Reads of a report are written to the report’s audit trail. Do not expose the response to the report subject or to any customer-facing surface, see Confidentiality.


List Reports

Retrieve reports for your client, most recently created first.

Endpoint

GET /v1/reports

Query Parameters

ParameterTypeRequiredDescription
statusstringNoFilter by status. Comma-separated values accepted, for example draft,pending_review. Default: all
reportTypestringNoFilter by report type. Comma-separated values accepted. Default: all
userIdstringNoFilter to reports about a single subject
transactionIdstringNoFilter to reports that include a given transaction
reportNumberstringNoLook up by your own internal report number
createdFromnumberNoUnix epoch milliseconds, only reports created at or after this time
createdTonumberNoUnix epoch milliseconds, only reports created at or before this time
pagenumberNoPage number for pagination (default: 1)
limitnumberNoResults per page (default: 20, max: 100)

Response Schema

FieldTypeDescription
reportsarrayList of report summaries
reports[].idstringOrca report identifier
reports[].statusenumCurrent status
reports[].reportTypeenumReport type
reports[].reportNumberstringYour internal report number
reports[].fiuReferenceNumberstringFIC reference number, once filed
reports[].titlestringReport title
reports[].userIdstringReport subject
reports[].transactionCountnumberNumber of transactions on the report
reports[].createdAtnumberCreation timestamp
reports[].updatedAtnumberLast update timestamp
reports[].submittedAtnumberFiling timestamp, if filed
totalnumberTotal reports matching the query
pagenumberCurrent page number
pagesnumberTotal number of pages

The list response carries summaries only. Use Get Report with include=content for the populated goAML content of a single report.

Example Response

{ "reports": [ { "id": "rep_01JQ4T8ZC7K2XN", "status": "pending_review", "reportType": "STR", "reportNumber": "CASE-2026-00841", "fiuReferenceNumber": null, "title": "STR: Deposits disproportionate to declared income", "userId": "USER123", "transactionCount": 3, "createdAt": 1754006400123, "updatedAt": 1754010000000, "submittedAt": null }, { "id": "rep_01JQ2R1AA9J8ML", "status": "submitted", "reportType": "STR", "reportNumber": "CASE-2026-00792", "fiuReferenceNumber": "113600000-0-0", "title": "STR: Transfers between linked accounts", "userId": "USER456", "transactionCount": 12, "createdAt": 1752800000000, "updatedAt": 1752900000000, "submittedAt": 1752900000000 } ], "total": 41, "page": 1, "pages": 3, "timestamp": 1754010500000 }

Responses

  • 200: Reports returned
  • 400: Bad request: invalid filter or pagination value
  • 401: Unauthorized
  • 403: Reporting not enabled for this client
  • 500: Internal server error
Last updated on