katch VERIFIED
Developer Documentation

Katch Verified API

Influencer intelligence for brands and agencies — brand-safety flags, traits, scores, and sentiment, on demand.
Version  v1 Base  api.katchdata.com/v1/verified Transport  HTTPS · TLS only Format  JSON
API Reference  ·  v1
katch.ai  ·  katchdata.com
Overview

Getting started

Submit a creator handle for analysis, then retrieve brand-safety flags, traits, scores, sentiment, and stats. Analyses run asynchronously and complete typically within minutes; you are notified by a signed webhook and retrieve results by influencer_id.

Base URL
https://api.katchdata.com/v1/verified
Authentication
Partner credential in the Authorization header. No Bearer.
Versioning
Version in the path (/v1). Breaking changes ship a new version.
Preview release. This API is under active development and may change as we incorporate early-partner feedback. We'll communicate changes ahead of time; pin to /v1 and treat unrecognized response fields as additive.
Authentication

Authorizing requests

Send the credential Katch supplies directly in the Authorization header:

Authorization: <partner credential>
Do not use Bearer
Send the raw credential — no Bearer prefix.
Do not use X-Api-Key
The credential goes in Authorization only.
Scoped to you
You can retrieve only influencers you submitted with this credential.
Status codes. A missing header returns 401; an invalid credential returns 403.
How it works

The analysis lifecycle

Analyses are asynchronous: you submit, Katch processes, and you collect results once they're ready. There is no job-status polling — drive completion off the webhook.

Your application Katch Verified API POST /analyze handle · platform · limit · webhook_url 200 · influencer_id, parent_job_id Analysis · ~5–30 min POST webhook · analysis_finished (signed) GET /results?influencer_id=… 200 · flags / traits / score / sentiment / stats
Service levels. Analyses typically complete in ~5–30 minutes, with a 24-hour reconciliation backstop for any that run long. If you don't register a webhook, retrieve results on your own schedule.
Endpoint

Start an analysis

POST/analyze

Start — or transparently reuse — an analysis for one account, or for several accounts belonging to the same influencer.

Two ways to identify the influencer. Send either a single account via top-level handle + platform, or an accounts array covering up to six social accounts for the same influencer (one handle per supported platform). Do not combine the two formats in one request. This is existing behavior — not a new or breaking change.

Request body

FieldReqDescription
handleeitherAccount handle, with or without @. Max 255 chars. Use with platform for a single account; omit when sending accounts.
platformeitherinstagram, tiktok, youtube, facebook, linkedin, or x. Pairs with a single top-level handle.
accountseitherArray of { "platform", "handle" } objects for the same influencer — up to six, one handle per supported platform. Alternative to top-level handle + platform; do not send both.
influencer_nameoptDisplay name. Defaults to the handle. Max 255.
limitoptPost cap for the analysis. 1–5000, default 50. Controls how much history is analyzed (by post count, not date range). Applies per account.
start_dateoptInclusive publication-date floor, formatted YYYY-MM-DD.
end_dateoptInclusive publication-date ceiling, formatted YYYY-MM-DD.
webhook_urloptPublic HTTPS completion endpoint. Max 2048. Must resolve to a public IP; no embedded credentials.
Request
curl --request POST \
  "https://api.katchdata.com/v1/verified/analyze" \
  --header "Authorization: $KATCH_VERIFIED_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "handle": "creator_handle",
    "platform": "instagram",
    "limit": 500,
    "webhook_url": "https://partner.example.com/hook"
  }'
Response · 200
{
  "influencer_id": 123,
  "influencer_name": "Creator Name",
  "parent_job_id": "123e4567-…-426614174000",
  "status": "queued"
}
Idempotent reuse. An equivalent active analysis is reused — status becomes already_queued with the existing parent_job_id. Persist influencer_id; it's how you retrieve results later.
Request · multiple accounts for one influencer
curl --request POST \
  "https://api.katchdata.com/v1/verified/analyze" \
  --header "Authorization: $KATCH_VERIFIED_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "accounts": [
      { "platform": "instagram", "handle": "creator_instagram" },
      { "platform": "tiktok", "handle": "creator_tiktok" },
      { "platform": "youtube", "handle": "creator_youtube" }
    ],
    "influencer_name": "Creator Name",
    "limit": 50,
    "start_date": "2026-01-01",
    "end_date": "2026-06-30",
    "webhook_url": "https://partner.example.com/hook"
  }'
Callback

Completion webhook

When an analysis completes, Katch sends a signed POST to your webhook_url.

Headers
Content-Type: application/json
X-Katch-Event: analysis_finished
X-Katch-Delivery: 123e4567-…-174000
X-Katch-Signature: sha256=<hex>
Body
{
  "type": "analysis_finished",
  "parent_job_id": "…174000",
  "influencer_id": 123,
  "has_errors": false,
  "count_total": 10,
  "count_success": 10,
  "count_fail": 0
}
Verify the signature (constant-time)
expected = "sha256=" + HMAC_SHA256( webhook_signing_secret, raw_body )
Acknowledge
Return 2xx. Failed deliveries retry up to 10 times.
Dedupe
The same event may arrive twice — dedupe on parent_job_id.
Partial results
If has_errors is true, fetch available results normally.
Endpoint

Retrieve results

GET/results

Retrieve results for an influencer you previously submitted. The view selects the projection.

flags
Flagged posts with red/yellow flag + explanation.
traits
Detected traits per post (flags without the flag).
score
Aggregate counts + ratios: safety, sales, quality.
sentiment
Sentiment toward a brand — pass brand_name.
stats
Post totals, date span, platform count.

Query parameters

ParameterNotes
influencer_idID returned by /analyze. Preferred. One identifier required.
handle + platformUsed when influencer_id is omitted. platform defaults to instagram.
viewflags · traits · score · sentiment · stats. Default flags.
brand_nameRequired for view=sentiment — the brand to measure sentiment toward. Ignored by other views. Max 255.
start_date / end_dateInclusive YYYY-MM-DD publication date filters.
limit / offsetPagination for list views. limit 1–1000 (default 100); offset 0–1,000,000.
List views · flags/traits/sentiment
{
  "influencer_id": 123,
  "view": "flags",
  "count": 1,
  "rows": [ … ]
}
score
{
  "view": "score",
  "analyzed_posts": 50,
  "brand_safety": {"posts":4,"ratio":.08},
  "sales": {"posts":12,"ratio":.24},
  "video_quality": {"posts":39,"ratio":.78}
}
stats
{
  "view": "stats",
  "total_posts": 50,
  "earliest_post": "2025-01-15 09:30:00",
  "latest_post": "2026-07-01 18:22:10",
  "platform_count": 2,
  "sponsored_posts": 7
}

Row fields · flags & traits

Rows in the flags and traits views share the same shape; flags rows add a flag severity.

FieldTypeDescription
video_idstringSource post identifier.
urlstringPermalink to the post.
platformstringinstagram, tiktok, youtube, facebook, linkedin, or x.
ut_idintegerUniversal trait id.
universal_traitstringTrait name (e.g. Mild Profanity).
category / sub_categorystringTrait taxonomy.
activation_scorenumberStrength of the trait in the post.
first_appearanceintegerMarker for where the trait first appears in the post.
is_sponsoredbooleanWhether the post is sponsored. May be null when undetermined.
publisheddatetimeYYYY-MM-DD HH:MM:SS.
explanationstringWhy the trait was detected.
flagstringflags view only. Roll-up severity — Red or Yellow.

Row fields · sentiment

FieldTypeDescription
video_idstringSource post identifier.
urlstringPermalink to the post.
platformstringPost platform.
brandstringBrand mentioned. Pass brand_name to filter to a single brand.
sentimentstringpositive, negative, or neutral.
publisheddateYYYY-MM-DD.
explanationstringBasis for the sentiment call.
Field formats. ut_id is an integer; published (flags/traits), earliest_post, and latest_post are datetimes (YYYY-MM-DD HH:MM:SS) while sentiment published is date-only (YYYY-MM-DD); is_sponsored is a boolean that may be null when undetermined.
Endpoint

List analyzed influencers

GET/influencers

List every influencer analyzed under your credential — the starting point for GET /results when you don't already hold an influencer_id. Credential-scoped: you see only your own.

Query parameters

ParameterNotes
limitPage size. Default 50.
offsetRow offset for pagination. Default 0.
Request
curl \
  --header "Authorization: $KATCH_VERIFIED_API_KEY" \
  "https://api.katchdata.com/v1/verified/influencers?limit=50&offset=0"
Response · 200
{
  "count": 2,
  "rows": [
    { "influencer_id": 298,
      "influencer_name": "Coco Lloyd",
      "created_at": "2026-07-30 04:12:08",
      "last_accessed_at": "2026-07-30 04:12:08" }
  ]
}
Auth behavior matches the rest of the API. A missing Authorization header returns 401; an invalid credential returns 403.
Reference

Errors & environments

Status codes

CodeMeaning
400Invalid request.
401Missing credential.
403Invalid credential or access not allowed.
404Influencer not found for your credential.
429Rate limited — wait for Retry-After.
500 / 502Transient — retry with backoff.

Handling & environments

Retries
Retry 500/502 with exponential backoff using the same body. Honor Retry-After on 429. Error bodies use {"error": "…"}.
EnvironmentStatus
Production
api.katchdata.com/v1/verified
Available
SandboxPlanned