Developers
API reference
Queue a Human Signal Brief from your own tools — a sequencer, a workflow builder, your CRM, a script. Same pipeline as the app, same source links, confidence ratings, and fact-check pass on every finding.
The short version
A brief is 60–120 seconds of live web research, so the API is async: POST a LinkedIn profile URL, get an id back immediately, poll it until the brief is ready. Authentication is a bearer key you mint in Settings. Every brief costs exactly one credit — the same credit an in-app brief costs.
Step 1
Authenticate
Create a key in Settings → API keys. The raw key is shown exactly once, at creation — we store only its hash, so we can't show it to you again (or to anyone who gets hold of our database). Treat it like a password: server-side only, never in a browser or a mobile app. Revoke a key in Settings and it stops working immediately.
Authorization: Bearer syk_live_…Keys inherit your account: usage is billed to it, and if your account access is disabled the keys stop with it.
Step 2
Queue a run
curl -X POST https://www.showyouknowme.com/api/v1/research \
-H "Authorization: Bearer $SYK_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"linkedInUrl":"https://www.linkedin.com/in/jane-mitchell","name":"Jane Mitchell"}'name is optional — the pipeline confirms the real name from the research itself. Idempotency-Key is optional but recommended; see idempotency.
202 Accepted
{
"id": "d3f0a1b2-…",
"status": "queued",
"pollUrl": "/api/v1/research/d3f0a1b2-…"
}Step 3
Poll for the brief
curl https://www.showyouknowme.com/api/v1/research/d3f0a1b2-… \
-H "Authorization: Bearer $SYK_API_KEY"Poll every 10–15 seconds; most runs finish inside two minutes. Status is one of queued, running, done, failed, or cancelled (you stopped it from the app).
{ "id": "d3f0a1b2-…", "status": "running" }
{ "id": "d3f0a1b2-…", "status": "done", "result": { …full brief… } }
{ "id": "d3f0a1b2-…", "status": "failed", "error": "…" }result is the same object the app renders: prospect, verdict (the one-sentence strategic call), topSignal with its hookAngle, personalSignals / professionalSignals (each with source, recency, confidence, and corroboration when a fact is multi-sourced), socialProfiles, notFound, and contactInfo.
A finished run is also a normal brief in your account — it appears in history, counts toward your reply-rate analytics, and can be shared or exported like any other.
Safety
Idempotency
Queuing spends a credit, so a retry after a dropped connection shouldn't buy a second brief. Send an Idempotency-Key header (8–255 printable characters — a UUID is ideal) and a repeat of the same request replays the original 202 instead of enqueuing again. Reusing a key with a different profile URL is an error (idempotency_key_reuse), never a surprise charge; a repeat that arrives while the first is still being processed gets 409.
It's best-effort: keys are honored for 24 hours and are held in the server's memory, so a deploy in between clears them. If a run absolutely must not be duplicated, poll before retrying.
Reference
Errors
Every error is { "error": true, "code": "…", "message": "…" }. Codes are stable; messages are for humans and may change.
| Status | Code | Meaning |
|---|---|---|
| 400 | bad_request | Not a LinkedIn profile URL, malformed JSON, or a malformed Idempotency-Key. |
| 401 | unauthorized | Missing, unknown, or revoked key. |
| 403 | forbidden | The account behind this key has been disabled. |
| 403 | trial_expired | Out of credits (the code name is kept for stability). Upgrade, or wait for your monthly reset — the 1st on free plans, your billing date on paid ones. |
| 403 | suppressed | This profile is excluded from research at the person's request. It will not become available. |
| 404 | not_found | No API run with that id on your account. |
| 409 | idempotency_in_flight | A request with this Idempotency-Key is still being processed. |
| 413 | payload_too_large | Request body exceeds 8 KB. |
| 422 | idempotency_key_reuse | This Idempotency-Key was already used for a different request body. |
| 429 | rate_limited | Too many requests. Honor the Retry-After header. |
| 429 | quota_exceeded | Monthly API brief quota reached. Retry-After counts to the reset. |
| 500 | write_failed / read_failed | We couldn't queue or load the run. Safe to retry — with the same Idempotency-Key, if you sent one. |
| 503 | quota_unavailable | Billing or quota couldn't be verified, so nothing was queued. Retry with backoff. |
Nothing is charged for an error response: credits are spent on completed briefs, and a run that finds too little to build a brief (failedwith a “not enough public info” message) isn't billed either.
Reference
Limits
- 10 requests/minute per key on
POST, 60/minute per key on polls. Both sendRetry-After. - Your plan's credits apply first: an API brief spends the same credit an in-app brief does, from the same monthly pool.
- A monthly API brief cap sits above that as a runaway-script backstop, scaled to your plan and reset on the 1st at 00:00 UTC: Free 25 · Starter 150 · Pro 600 · Scale 2000. In normal use your credits run out first — that's the design.
- Request bodies are capped at 8 KB, and browser (cross-origin) calls are intentionally unsupported — a key belongs on a server, not in a page.
Need more than this? Email hello@showyouknowme.com — the ceilings are defaults, not policy.
Before you build
What the API won't do
The API is the same product, which means it carries the same refusals. Briefs never include health, family, religion, politics, or the other categories our selection policy rules out, however public they are. Anyone who asks to be excluded is excluded globally — for every account, through every surface, including this one. And research runs on LinkedIn profile URLs only; there is no bulk-enumeration or list-building endpoint, by design.
What you do with a brief is yours to answer for: once it's in your systems you're an independent controller of that data under data-protection law. The terms spell that out.