Get started

Authentication

API keys, getting a free key, and security best practices.

The ChangeThisFile API uses bearer tokens. Every request to /v1/* (except POST /v1/keys/free) must include an Authorization header:

Authorization: Bearer ctf_sk_...your_key_here...

API key format #

PrefixMeaning
ctf_sk_…Standard secret key — server-side use only. Full read/write access to your account.
whsec_…Webhook signing secret. Returned by POST /v1/webhooks/secret. Not an API key — used to verify HMAC signatures on incoming webhooks.

Keys never expire automatically. Rotate them from the dashboard or via POST /v1/keys/rotate.

Get a free key #

curl -X POST https://changethisfile.com/v1/keys/free \
     -H "Content-Type: application/json" \
     -d '{"email":"you@example.com"}'

Response (key shown once — store it now):

{
  "api_key": "ctf_sk_...full_key...",
  "plan": "free",
  "monthly_limit": 1000,
  "message": "Save this key — it will not be shown again."
}

The free tier includes 1,000 conversions/month, a 25 MB file cap, and a 10 req/min throttle. Upgrade via POST /v1/billing/checkout or in the dashboard.

Security best practices #

Never expose secret keys in client-side code

ctf_sk_… keys grant full account access. Always proxy through your backend — never embed them in browser bundles, mobile apps, or any code your end users can inspect. If a key leaks, rotate it immediately.

Use environment variables, not config files

Store keys in environment variables (e.g. CTF_API_KEY) and load them at runtime — never hard-code them in source files that might end up in a public repo.

export CTF_API_KEY="ctf_sk_..."
curl -X POST https://changethisfile.com/v1/convert \
     -H "Authorization: Bearer $CTF_API_KEY" \
     -F "file=@photo.png" -F "target=jpg" -o photo.jpg
Rotate after every leak — and on a schedule

Suspect a key was logged, pushed to a public repo, or pasted in chat? Rotate it. The dashboard supports zero-downtime rotation: create a new key, deploy it, then revoke the old one. We recommend rotating on a quarterly cadence at minimum.

Verify every webhook signature

Webhook URLs are publicly reachable by definition. Always verify X-CTF-Signature with constant-time HMAC compare before trusting the payload — and reject timestamps older than 5 minutes. See Webhooks for ready-to-paste snippets in Python, Node, and PHP.

Set tight HTTP timeouts on your callers

The conversion endpoint streams large binaries — don't let a stuck upstream hang your worker. Set a per-request timeout of 60-600s based on the largest file you'll process.

Auth errors #

Statuserror.codeWhat it means
401invalid_api_keyHeader missing, malformed, or revoked key. Re-issue from the dashboard.
429quota_exceededMonthly conversion quota hit. Free tier hard-stops; paid tiers fall through to overage at the per-conversion rate.
429rate_limitedToo many requests in a 60-second window. Honor the Retry-After header.