Overview
A report is how you tell ChainPatrol about a threat. Each report bundles one or more assets — the URLs, domains, social handles, or blockchain addresses you want acted on — with the context and evidence our review team needs to act. Everything goes throughPOST /report/create. Evidence files
are the one thing that needs a separate call first: files are uploaded to
POST /attachment/upload, which returns URLs you then
pass to report.create.
Attachments are optional. If you have no files to send, skip step 2 entirely and call
report.create on its own. And if you already host your evidence somewhere publicly
reachable, put those URLs straight into attachmentUrls — the upload endpoint exists so
that you do not have to host them.Before you start
You need:- An API key, sent as
X-API-KEYon every request. See Authentication. - Your organization slug — the identifier in your dashboard URL
(
https://app.chainpatrol.io/<slug>). If your key is scoped to a single organization you can omitorganizationSlugand we will use the key’s organization.
https://app.chainpatrol.io/api/v2.
The flow
1
Check for an existing report (optional)
If your pipeline can rediscover the same threat, check first with
POST /reports/search. Re-reporting an asset that
already has a pending report fails with a 422 and a REPORT_ALREADY_EXISTS error, so
searching first keeps your error rate meaningful.2
Upload your evidence files
Send each file to Nothing is attached to a report yet — the upload only stores the file and hands you a
URL. Multipart lets you send up to 10 files in one request; the 4 MB limit applies to
the whole request body.
POST /attachment/upload and keep
the URLs it returns. .eml message files, screenshots, PDFs, and more are supported —
see supported file types.Response
3
Create the report
Call Keep the
POST /report/create with your assets and the
attachment URLs from the previous step.Response
id — it is how the report is identified in the dashboard and in
GET /organization/reports.4
Track what happens next
The report goes to review. Images you attached appear inline on the report; other files
are listed as downloadable evidence, and our takedown team can forward them to the
registrar or hosting provider — which is why a raw
.eml is worth more than a
screenshot of one.Poll GET /organization/reports for status,
or configure a webhook to be notified when asset
statuses change instead of polling.Complete example
Upload and report in one script: two files go up in a single multipart request, and both URLs are attached to one report.Report fields
The fields you will use most. The full schema, including every optional field, is on the Create Report reference page.organizationSlug, discordGuildId, and telegramGroupId are three ways to name the
same thing. Use organizationSlug unless you are building a Discord or Telegram
integration and only have the platform’s ID to hand.Attachments in more detail
- Any file type on the supported list, not just images. The upload endpoint accepts
.emland.msgmessages, PDFs, Word documents, CSVs, plain text, and the common image formats. - Images are displayed, other files are listed. We classify by extension: image extensions render inline on the report, everything else appears as a downloadable file.
- Non-image files can go out with the takedown. Our team can attach them to the email sent to a registrar or hosting provider, using the file name you uploaded — so name files descriptively.
- Self-hosted URLs still work. Anything in
attachmentUrlsis stored as given. If you host evidence yourself, keep those links alive; we cannot re-fetch a link that has expired. - Attach files to the report that they are evidence for. Attachments belong to the report as a whole, not to an individual asset, so if two threats are unrelated, file two reports.
Handling errors
report.create returns 422 Unprocessable Content when the request is well-formed but the
assets cannot be reported — the most common outcome to code against. The response carries
one entry per failing asset in data.errors, each with an errorType, a message, and a
suggestion:
422 means no report was
created. Fix or drop the offending assets and resubmit. Every errorType is listed on the
Create Report reference page.
For upload failures, see
error responses on the Upload Attachment
page.
Best practices
- One report per threat, several assets per report. If a phishing campaign spans a site, a Twitter handle, and a wallet address, put all three in one report — the shared context is what makes them reviewable together.
- Search before you submit if your pipeline can rediscover the same asset.
- Send raw
.emlwhen you have it. The headers are what email providers and registrars act on; a screenshot of an email is much weaker evidence. - Include a description a human can act on. What was the lure, where was it seen, who reported it.
- Set
brandSlugwhen you know which brand is being impersonated — it saves a review step. Fetch valid slugs from List Organization Brands. - Do not retry a
422unchanged. It is a validation outcome, not a transient failure. Retry5xxwith exponential backoff.
Other ways to create reports
CLI
chainpatrol reports create files a report from the terminal, including
--attachment-url for evidence you have already uploaded.Dashboard
Your team can create reports by hand and drag evidence files straight onto them.
Security Portal
A public submission form for your community, with no login required.
Bots
Discord, Telegram, and Slack bots let your community report from where they already are.
The CLI and the JavaScript SDK take attachment URLs, not files. To upload a file
today, call
POST /attachment/upload directly and pass
the URL it returns.