For developers

Applying for and using the TestedClear API

The TestedClear API lets you verify a user's sexual health credential from inside your own product — dating apps, telehealth platforms, event-management software, anything that benefits from trustworthy verified-clear status. This guide covers everything from application to production traffic.

What's in this guide

1. Applying for access

Go to /developers and click Apply for API access. You'll provide:

  • Company name and website
  • Use case — one paragraph on what you're building and how verification fits in
  • Expected volume — rough monthly verification calls
  • Contact name and email

We review every application manually. Approval typically takes 1–3 business days. You'll receive an email when your application is reviewed, with a link to your developer dashboard. While the application is pending, you can still preview the API documentation and read this guide.

Use cases we approve quickly: dating apps wanting to display verification status on profiles, telehealth platforms verifying patient testing history, event-management products gating ticket sales on verification. Use cases that require more review: anything involving aggregating verification data, marketing to verified users without their consent, or scraping the verify endpoint.

2. Pricing tiers

Once approved, you start on the free Developer tier. You can upgrade self-serve through your dashboard at any time. All tiers share the same endpoints and rate limits per request — the difference is monthly included calls and overage rate.

TierMonthlyIncludedOverage
DeveloperFree100 / mo$0.25 / call
Starter$1492,000 / mo$0.20 / call
Growth$59915,000 / mo$0.12 / call
Scale$1,99975,000 / mo$0.08 / call

Need higher volume than Scale, a custom BAA, dedicated support, or per-region SLAs? Email partners@testedclear.com for Enterprise pricing.

How calls are counted. Each successful call to GET /api/v1/verify or GET /api/v1/badge counts as one verification. Failed authentication (401), invalid tokens (404), and revoked credentials (200 with verified:false) all still count — they consume an authenticated request. Errors caused by our infrastructure (5xx) do not count.

3. Authentication

Every request requires an API key passed in the X-API-Key header. You can also use the Authorization header with a Bearer prefix if your HTTP client prefers that pattern — both work.

curl https://www.testedclear.com/api/v1/verify?token=tc_abc123 \
  -H "X-API-Key: tc_test_yourkeyhere"

Keys come in three prefixes:

  • tc_test_ — sandbox keys, isolated from production data. Free to use, included with every approved application.
  • tc_live_ — production keys, billed against your tier. Activated when you upgrade past the Developer tier.
  • tc_badge_ — restricted keys for badge-display use only. Cannot call the verify endpoint, only badge.
Never expose live keys client-side. Keys belong on your server. If a key leaks, rotate it immediately from your developer dashboard. Suspended keys return 403 with a contact pointer to partners@testedclear.com.

4. The verify endpoint

GET /api/v1/verify?token=<token> — the core endpoint. Pass a credential token (the one a TestedClear user shared with you), get back a verification result.

Request

curl https://www.testedclear.com/api/v1/verify?token=tc_abc123 \
  -H "X-API-Key: tc_live_yourkeyhere"

Successful response (verified, current)

{
  "verified": true,
  "panel": "essential",
  "tested_date": "2026-04-15",
  "retest_by": "2026-10-15",
  "issuer_type": "clinic",
  "status": "current"
}

Successful response (revoked)

{
  "verified": false,
  "reason": "revoked"
}

Successful response (expired)

When a credential is past its retest-by date, the response still returns 200 but with status: "expired" and verified: false. Treat it the same as "not verified" in your UI — but you can surface a softer message like "testing date is past the recommended window" instead of a hard rejection.

Field reference

  • verified — boolean. True if the credential is current and valid.
  • panelessential (HIV, Hep B, Hep C, Chlamydia, Gonorrhea, Syphilis) or complete (Essential + Trichomoniasis).
  • tested_date — ISO date the test was administered.
  • retest_by — ISO date the credential will auto-expire.
  • issuer_typeclinic, quest, labcorp, or at_home.
  • statuscurrent, expired, or revoked.

5. The badge endpoint

GET /api/v1/badge?token=<token>&format=html — returns a renderable badge for embedding in your UI. Use this when you want to display the TestedClear visual badge instead of constructing your own UI from the verify response.

Two output formats:

  • format=json (default) — same shape as the verify endpoint
  • format=html — a self-contained HTML snippet you can drop into an iframe or directly into your page

The HTML format is the easiest path if you want the canonical TestedClear visual brand without rebuilding the badge yourself.

6. Error handling

Standard HTTP status codes. Every error response includes a docs URL pointing back to /developers and an apply URL for unauthenticated callers.

StatusMeaningWhat to do
200OK — check verified fieldRender verification result based on payload
400Missing or malformed query parameterConfirm token is present and properly URL-encoded
401Missing or invalid API keyVerify the X-API-Key header is set and the key is correct
403Key is suspendedEmail partners@testedclear.com
404Token not foundDisplay "not a valid TestedClear link" to your user
429Rate-limited or monthly quota exceededBack off, or upgrade your tier
5xxServer error on our sideRetry with exponential backoff (max 3 attempts). Doesn't count against quota.

Idempotency

All endpoints are read-only and idempotent. Retrying a failed request never causes duplicate effects. You don't need to track idempotency keys.

7. Upgrading your tier

Open your developer dashboard at /developers/dashboard/<applicationId>. The current tier and your usage this month are at the top. Below that, the tier picker shows every option and a "Upgrade to [tier]" button.

Click upgrade, complete Stripe checkout, and your live key activates immediately. Your sandbox key keeps working alongside the live key for ongoing testing — they bill separately (sandbox is always free).

Downgrades require contacting partners@testedclear.com. We do this manually because most tier changes also involve renegotiating volume forecasts and any active BAA.

8. The developer dashboard

/developers/dashboard/<applicationId> is your single pane of glass. It shows:

  • Current tier and monthly usage as a percentage of the included quota
  • API keys — every key issued for your application, with last-used timestamps and a copy button on the active one
  • Recent calls — the last 100 verification calls (timestamp, endpoint, response status). Useful for debugging integration issues.
  • Tier picker with self-serve upgrade buttons
  • Manage billing — link to your Stripe billing portal to update payment method, view invoices, or cancel

Bookmark this URL — there's no top-level navigation to it from the marketing site (yet). The link is in your approval email and in any subsequent invoice email.

9. Common issues

I'm getting 401 even though my key looks right

Confirm the header name is exactly X-API-Key(case-insensitive but spelled out fully). Some HTTP clients silently drop unknown headers when they don't look like "allowed" ones — wrap the value in quotes if your client uses a config file format that strips them.

The token a user gave me returns 404

Most common cause: it's a one-time link that's already been viewed. One-time links expire on first use, including a verify-endpoint call (the system can't tell the difference between "a partner viewed it" and "an integration verified it"). For repeated verification, ask your user for a PIN-protected link or a vanity URL — both can be verified multiple times.

I'm hitting 429 in my sandbox

Sandbox shares the same per-minute rate limit as live (60 calls/minute). The monthly quota of 100 calls is for the Developer tier specifically — sandbox testing on a paid tier draws against your tier's included quota.

How do I know if a credential has been revoked?

The verify endpoint returns verified: false and reason: "revoked" with a 200status. Don't cache verification responses for more than the recommended retest interval — credentials can be revoked between the time you verified and the time you display the badge.

Can I get a webhook when a credential I've verified gets revoked?

Webhooks aren't shipped yet. For now, re-verify on each user-facing page-load that depends on the verification, or implement a daily background re-check. Webhook subscriptions are on the Enterprise roadmap — email partners@testedclear.comif it's a hard requirement for your integration.

Do you offer SDKs?

Not yet. The API is small enough (two endpoints, simple JSON shape) that we've seen partners ship integrations in well under a day with a plain HTTP client. If you'd benefit from a typed client (TypeScript, Python, Go), let us know which language — we prioritize SDK work based on demand.

Need integration support?

Email partners@testedclear.comwith your application ID and we'll route you to engineering. Enterprise customers get a dedicated Slack channel.