Frank Public API — Developer Guide

Read-only access to your researches, their interviews, and transcripts.

Base URL       https://api.hifrank.ai
Version          All endpoints are under /v1
Auth               Authorization: Bearer frank_sk_live_...

On this page

  1. Create an API key
  2. List your researches
  3. List a research's interviews
  4. Get one interview + transcript
  5. Errors

1. Create an API key

Create a key in the app under Settings → API keys (shown once — copy it right away). Send it as a Bearer token on every request:

Authorization header Copy
Authorization: Bearer frank_sk_live_...

2. List your researches

Get /v1/researches

Returns every research you have access to (newest first).

curl Copy

curl https://api.hifrank.ai/v1/researches \
-H "Authorization: Bearer frank_sk_live_..."

200 · Response Copy

[
{
  "researchId": "6b2f8c10-...",
  "title": "Trial churn discovery",
  "status": "active",
  "type": "discovery",
  "goals": ["Understand why trial users don't upgrade"],
  "productId": "d91c8f22-...",
  "createdAt": "2026-01-01T10:00:00.000Z"
}
]

3. List a research's interviews

GET /v1/researches/{researchId}/interviews

Returns interview summaries (newest first, no transcript). Use it to discover interview IDs, then fetch the full transcript per interview.

curl Copy

curl https://api.hifrank.ai/v1/researches/6b2f8c10-.../interviews \
 -H "Authorization: Bearer frank_sk_live_..."

200 · Response Copy

[
 {
   "interviewId": "2b7f8c10-...",
   "researchId": "6b2f8c10-...",
   "status": "completed",
   "type": "audio",
   "participant": { "name": "Jane", "email": "jane@acme.com" },
   "startedAt": "2026-01-01T10:00:00.000Z",
   "endedAt": "2026-01-01T10:20:00.000Z",
   "duration": 1200
 }
]

4. Get one interview + transcript

GET /v1/interviews/{id}

200 · Response Copy

{
 "interviewId": "2b7f8c10-...",
 "researchId": "6b2f8c10-...",
 "status": "completed",
 "type": "audio",
 "participant": { "name": "Jane", "email": "jane@acme.com" },
 "startedAt": "2026-01-01T10:00:00.000Z",
 "endedAt": "2026-01-01T10:20:00.000Z",
 "duration": 1200,
 "transcript": [
   { "sequence": 1, "role": "assistant", "text": "Hello…", "startTimestamp": "…", "endTimestamp": "…" },
   { "sequence": 2, "role": "user", "text": "Hi…", "startTimestamp": "…", "endTimestamp": "…" }
 ]
}

Errors

Every error uses one envelope:

Error envelope    Copy

{
 "error": {
   "code": "not_found",
   "message": "Interview not found",
   "requestId": "req_1a2b3c"
 }
}

STATUS   code                  When

400     validation_error      malformed id in the path

401     invalid_api_key       missing / invalid / revoked key

404     not_found             research / interview not yours (or absent)

429     rate_limited          rate limit hit — retry after Retry-After seconds

Every response carries an x-request-id header — include it when reporting issues.