API/Reference

Account

API reference

Markdown

A small REST API for inspecting, cleaning and rewriting text and files, included with every plan. Base URL /api/v1. Create a key from API keys.

Authentication

Send the key as a bearer token. Keys are stored hashed, so the full value is shown once at creation and cannot be recovered afterwards.

curl https://gifi.ai/api/v1/usage \
  -H "Authorization: Bearer wmr_live_..."

Rate limits and credits

Limits are per key, per minute. Every response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset (seconds until the window rolls over), so you can pace yourself without waiting for a 429. A 429 adds Retry-After.

PlanRequests/minCredits/month
Starter30300
Pro1201,500
Business6006,000

Text inspect and text clean cost no credits. Cleaning a file costs one. Rewriting costs one credit per candidate. Failed jobs are refunded automatically, so you are never charged for work that did not complete.

POST /api/v1/inspect

POST/api/v1/inspectfree

Reports what is present without modifying anything.

curl -X POST https://gifi.ai/api/v1/inspect \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello\u200bworld"}'
curl -X POST https://gifi.ai/api/v1/inspect \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d "{\"file\": \"$(base64 -i photo.jpg)\", \"filename\": \"photo.jpg\"}"

Text returns verifiable (each codepoint found, with offsets) and bestEffort (the writing-style heuristic). Files return the same findings the browser preview shows. They are separate because one is a countable fact and the other is a judgement.

POST /api/v1/clean

POST/api/v1/cleantext free · file 1 credit

Cleans text, or a file sent inline as base64.

curl -X POST https://gifi.ai/api/v1/clean \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "The model\u2014which is large\u2014works."}'
curl -X POST https://gifi.ai/api/v1/clean \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d "{\"file\": \"$(base64 -i photo.jpg)\", \"filename\": \"photo.jpg\"}"

Inline files are capped at 3 MB, because the platform limits request bodies to 4.5 MB and base64 inflates a file by a third. Use the web app’s direct upload for anything larger.

POST /api/v1/rewrite

POST/api/v1/rewrite1 credit per candidate

Rewrites text so a statistical trail is no longer the original sequence. Best-effort.

curl -X POST https://gifi.ai/api/v1/rewrite \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "Paste the marked prose here.", "strength": "paraphrase"}'

You pick strength (paraphrase, humanize, code, backtranslate, structural). Routing is ours. The response does not name a host or model. A rewrite does not certify that any vendor detector will fail.

GET /api/v1/usage

GET/api/v1/usagefree

Credit balance, plan limits and the last 30 days of usage.

curl https://gifi.ai/api/v1/usage \
  -H "Authorization: Bearer $KEY"

Getting started

There is no sales call and no waiting list. Sign up, create a key, make the call.

  1. 1Inspecting text and cleaning invisible Unicode are free and run in your browser at https://gifi.ai — no account, no key, nothing uploaded.
  2. 2Create an account and issue a key yourself at https://gifi.ai/api-keys. It is shown once and stored only as a hash.
  3. 3POST /api/v1/inspect costs no credits, so you can exercise authentication and the response shape before spending anything.
  4. 4Or issue a test key (mode: "test") and run the whole API — including file cleaning — without a subscription and without spending a credit. See Sandbox below.
  5. 5A plan is required for the billed endpoints — file cleaning and rewriting. Plans and limits are at https://gifi.ai/pricing.

Scopes are chosen per key, so a key issued for an agent can carry inspect alone and be unable to spend.

Sandbox

Create a test key and the whole API works without a subscription and without spending a credit. Keys beginning wmr_test_ run in sandbox; keys beginning wmr_live_ bill normally.

Sandbox is not a mock. Authentication, scopes, validation, rate limits and the cleaning engine are the real ones — a file you send is genuinely stripped and the actions you get back are the actions that were taken. What it does not do is spend credits or record a job, so nothing reaches your history and there is nothing for a retry to double-charge. Rewriting is the one exception: it returns the real response shape with your text unchanged, because calling a language model costs real money and inventing a rewrite would make an integration look correct while the output was a fiction.

Create one at https://gifi.ai/api-keys and choose "Test".

Errors

Failures are RFC 9457 problem documents, served as application/problem+json. Branch on code, not on the message: the message is written for a person and may be reworded.

{
  "type": "https://gifi.ai/docs#error-insufficient_credits",
  "title": "Insufficient credits",
  "status": 402,
  "detail": "Not enough credits",
  "code": "insufficient_credits",
  "hint": "Top up or upgrade at /pricing, then retry.",
  "retryable": false,
  "error": "Not enough credits"
}
invalid_request400Invalid requestnot retryable
Fix the request body and send it again. Retrying it unchanged will fail the same way.
unauthenticated401Not authenticatednot retryable
Send a valid key as Authorization: Bearer <key>. Create one at /api-keys, or see /auth.md for the OAuth flow.
insufficient_credits402Insufficient creditsnot retryable
Top up or upgrade at /pricing, then retry. GET /api/v1/usage shows the current balance.
insufficient_scope403Missing scopenot retryable
Issue a key that carries the scope this endpoint needs, or request it during the OAuth flow.
subscription_required403No active subscriptionnot retryable
The API needs a plan. See /pricing. This is an account state, not a problem with the request.
not_found404Not foundnot retryable
Check the identifier. The same answer is returned whether a record belongs to another account or never existed, so this is not a signal that it exists elsewhere.
unsupported_format415Unsupported formatnot retryable
Gifi would rather refuse than return a partial strip. Call /api/v1/inspect first to see whether a format is supported.
payload_too_large413Payload too largenot retryable
Send a smaller file. Inline bodies are capped because the platform limits requests to 4.5 MB and base64 inflates a file by a third.
processing_failed422Processing failedretryable
Credits for a failed job are refunded automatically, so a retry costs you nothing beyond the call. If it fails twice on the same input, the input is the problem.
idempotency_in_flight409Idempotency key already in flightretryable
An earlier request with this Idempotency-Key has not finished. Wait and retry the same key — do not send a new one, or the work may run twice.
idempotency_key_reused422Idempotency key reused with a different bodynot retryable
This Idempotency-Key was already used for a different request. Generate a fresh key for a new request; reuse it only to retry the identical one.
rate_limited429Rate limitedretryable
Wait for the number of seconds in Retry-After, then retry. RateLimit-Reset says when the window rolls over.
internal_error500Internal errorretryable
This one is ours. Retry with backoff; if it persists, send the response code and the time to support@gifi.ai.
not_configured503Capability not configurednot retryable
This deployment cannot serve that endpoint. Retrying will not help until it is configured.
service_unavailable503Temporarily unavailableretryable
A dependency is down. Retry with exponential backoff.

Retrying safely

Send an Idempotency-Key on POST /api/v1/clean and POST /api/v1/rewrite. The key is scoped to your account and the endpoint, bound to a hash of the body, and remembered for 24 hours.

Retrying with the same key and the same body replays the stored response with Idempotency-Replayed: true instead of repeating billed work. Reusing a key with a different body returns 422 rather than silently replaying the wrong answer. A retryable failure releases the key, so a refunded job can genuinely be retried.

Pagination

GET /api/v1/jobs is cursor-paginated. Read pagination.nextCursor and pass it back as cursor; null means the last page.

The cursor is anchored to the last row you saw rather than an offset, so jobs created while you page do not shift rows across page boundaries and make you read one twice.

Versioning

The major version is in the path. Additive changes ship in place, so ignore response fields you do not recognise.

A breaking change ships under a new path (/api/v2) rather than altering /api/v1 underneath you. A retiring operation returns Deprecation and Sunset response headers first, with at least 90 days between the announcement and the removal.

The machine-readable description is at /openapi.json.

MCP

Agents can call the same inspect, clean, rewrite and usage surface over MCP. Connect steps live on the agents page. Endpoint https://gifi.ai/mcp.

The server speaks OAuth 2.1 with PKCE S256 and Client ID Metadata Documents.

How to connect.

Scope of what the API can promise

Character removals and metadata actions are verifiable: every response names what was removed and you can confirm it independently. The writing-style score and any rewrite are best-effort. Nothing here certifies that content will pass or fail a third party’s AI detector — vendors publish neither detectors nor keys, so no tool can honestly make that claim. See terms for acceptable use.