Skip to main content

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 through POST /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-KEY on 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 omit organizationSlug and we will use the key’s organization.
All endpoints are served from 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 POST /attachment/upload and keep the URLs it returns. .eml message files, screenshots, PDFs, and more are supported — see supported file types.
Response
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.
3

Create the report

Call POST /report/create with your assets and the attachment URLs from the previous step.
Response
Keep the 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 .eml and .msg messages, 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 attachmentUrls is 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:
All assets must be valid for the report to be created — a 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 .eml when 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 brandSlug when you know which brand is being impersonated — it saves a review step. Fetch valid slugs from List Organization Brands.
  • Do not retry a 422 unchanged. It is a validation outcome, not a transient failure. Retry 5xx with 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.