Skip to content

API

Scan files for personal information and get cleaned copies back, from your own code.

Keys come from your account. Create and revoke them at your account. A key is shown once, when it is created — only a SHA-256 of it is stored, so we cannot show it to you again.

Files are never stored. Uploaded bytes are held in memory for one request and are not written to disk, to a database, or to a log. Previews in findings are always masked. More on privacy

Getting started

Authenticate with an API key in the x-api-key header. Keys look like isk_live_…, and we store only a SHA-256 of yours — if you lose it, we cannot recover it and you will need a new one.

Limits: 20 MB and 30 seconds per file, 30 requests per minute per key, 10 per minute per IP without one. Every error has the same shape:

{ "error": { "code": "payload_too_large", "message": "The file is larger than the 20971520 byte limit." } }

The full machine-readable spec is at /api/v1/openapi.json (OpenAPI 3.1, generated from the same schemas that validate your requests).

Endpoints

GET/api/v1/healthauth: None

Liveness check.

curl https://incognitoshare.com/api/v1/health
200
The service is up.

GET/api/v1/rulesauth: None

The current rule pack.

Cacheable. Send `If-None-Match` with the previous `ETag` to get a 304. The pack is immutable once published, so its version is a sound ETag.

curl https://incognitoshare.com/api/v1/rules \
  -H 'if-none-match: "2026.10.2"'
200
The current pack.
304
Your cached copy is current.

POST/api/v1/scanauth: API key

Check a file for personal information.

The file is read into memory, scanned, and discarded. Nothing is stored. Finding previews are masked before they leave the process.

curl -X POST https://incognitoshare.com/api/v1/scan \
  -H "x-api-key: $INCOGNITOSHARE_API_KEY" \
  -F "file=@holiday.jpg"
200
The scan result.
401
No API key, or the key is not valid.
413
The file is over the size limit.
415
The body was not multipart/form-data.
422
OCR was requested but is unavailable.
429
Rate limit exceeded.
504
The file took too long to process.

POST/api/v1/sanitizeauth: API key

Remove hidden data from a file.

Returns the cleaned bytes. `X-Removed` and `X-Remaining` carry base64url-encoded JSON arrays of plain-language labels — the kind of thing removed, never its value. Visible document content is not rewritten.

curl -X POST https://incognitoshare.com/api/v1/sanitize \
  -H "x-api-key: $INCOGNITOSHARE_API_KEY" \
  -F "file=@contract.docx" \
  -D headers.txt -o contract-clean.docx

# What was removed:
grep -i '^x-removed:' headers.txt | cut -d' ' -f2 | tr -d '\r' | base64 -d
200
The cleaned file.
401
No API key, or the key is not valid.
413
The file is over the size limit.
429
Rate limit exceeded.
504
The file took too long to process.

POST/api/v1/scan-eventsauth: Optional API key

Record an anonymous usage event.

Categories and counts only. Any field that looks like file content — a filename, a hash, a preview — is rejected with a 400.

curl -X POST https://incognitoshare.com/api/v1/scan-events \
  -H 'content-type: application/json' \
  -d '{"client":"web","fileType":"image","findingTypes":["gps_location"],
       "riskLevel":"high","action":"scanned"}'
202
Accepted.
400
Invalid, or an attempt to send content.
429
Rate limit exceeded.

POST/api/v1/waitlistauth: None

Join the launch waitlist.

Idempotent: signing up twice returns `already_present`, not an error.

curl -X POST https://incognitoshare.com/api/v1/waitlist \
  -H 'content-type: application/json' \
  -d '{"email":"you@example.com","source":"web"}'
200
Added, or already there.
400
The email address is not valid.
429
Rate limit exceeded.

GET/api/v1/meauth: API key

The caller, their plan, and what is left today.

Answers for a session cookie or an API key. Reports counts only — never what was scanned.

curl https://incognitoshare.com/api/v1/me \
  -H "x-api-key: $INCOGNITOSHARE_API_KEY"
200
The account.
401
Not signed in and no API key supplied.

POST/api/v1/usage/consumeauth: API key

Charge one check against today's allowance.

Called by the website before it checks a file. The body carries a size and a file kind — the file itself is read in a web worker and never leaves the device, so there is nothing else to send. This is accounting, not access control.

# Called by the website before it checks a file. A size and a
# file kind — the file itself is read in your browser and never sent.
curl -X POST https://incognitoshare.com/api/v1/usage/consume \
  -H "x-api-key: $INCOGNITOSHARE_API_KEY" \
  -H 'content-type: application/json' \
  -d '{"fileType":"image","bytes":248134}'
200
Counted.
400
Invalid body, or a field that is not allowed.
401
Not signed in and no API key supplied.
413
The file is larger than the plan allows.
429
The day's allowance is spent, or the rate limit was hit.

POST/api/v1/admin/planauth: Admin token

Set a user's plan. Temporary.

Behind `ADMIN_TOKEN`, and only exists because there is no payment provider yet. It goes away when billing arrives.

# Temporary, until there is a way to pay.
curl -X POST http://localhost:3000/api/v1/admin/plan \
  -H "x-admin-token: $ADMIN_TOKEN" \
  -H 'content-type: application/json' \
  -d '{"email":"you@example.com","plan":"pro"}'
200
Changed.
400
Invalid body, or an unknown plan.
403
Missing or wrong admin token.
404
No account with that address.

GET/api/v1/api-keysauth: API key

List your own keys. Never returns a key itself.

# Needs a browser session. See /account.
200
The keys.
401
Not signed in.

POST/api/v1/api-keysauth: API key

Create a key for the signed-in account.

Needs a browser session: an API key cannot mint API keys, because a key that can issue keys cannot meaningfully be revoked. The full key is returned exactly once — only a SHA-256 of it is stored.

# Needs a browser session, so this is done at /account rather than
# with curl. An API key cannot mint API keys.
201
Created.
400
Invalid body.
401
Not signed in.
403
An API key was used instead of a session.

DELETE/api/v1/api-keys/{id}auth: API key

Revoke one of your own keys.

# Needs a browser session. See /account.
200
Revoked.
401
Not signed in.
404
No active key with that id — it does not exist, is already revoked, or belongs to someone else. The three are not distinguished on purpose.

What the API will not do

  • Store your file, or anything derived from it beyond a count of bytes processed for billing.
  • Return an unmasked sensitive value. Previews show at most four characters, and GPS coordinates none at all.
  • Call a file “safe”. A riskLevel of none means our checks found nothing, which is not the same thing.
  • Rewrite the visible content of a document. Sanitizing removes metadata, comments, edit history and attachments; a phone number in a paragraph stays, flagged as fixable: false.