Skip to content
VEXKIO/ docs
QuickstartAPI ReferenceGuidesExamples
Dashboard
  • Overview
  • Quickstart
  • Authentication
  • Errors and rate limits
All endpoints (33)
Core APIs
  • Emotions API
  • Voice API
  • Fusion API
  • Signs API
Verticals
  • VEXKIO Copilot
  • VEXKIO Coach
  • VEXKIO Learn
  • VEXKIO Call
  • VEXKIO Sales
  • VEXKIO Research
  • VEXKIO Wellbeing
  • VEXKIO Telemedicine
  • VEXKIO Real Estate
  • VEXKIO Finance
  • VEXKIO Interview
  • NEXUS CRM
Disruptive
  • VEXKIO Studio
  • VEXKIO Negotiations
  • VEXKIO Live
  • VEXKIO Podcast
  • VEXKIO White-label
Platform
  • VEXKIO Analytics
  • VEXKIO Data Insights
  • VEXKIO Simulator
  • VEXKIO OEM SDK
B2C
  • VEXKIO Mirror
  • VEXKIO Kids
Social Impact
  • VEXKIO Signs
  • VEXKIO Signs Edu
  • VEXKIO Signs Enterprise
  • VEXKIO Edu
  • VEXKIO Rehab
  • VEXKIO Therapy Voice
  • All endpoints
  • Status page
  • Marketing site
  • Dashboard
API Reference / Core APIs

Signs API

Hand-shape REST endpoint. Base64 image or 21+ hand landmarks.

Endpoint
POST /signs
Auth
Bearer api_key
Price
$0.07 per session

Request

POST a JSON object. The fields below are the ones the handler reads; anything else in the body is ignored. Every rule in the table was transcribed from supabase/functions/signs/index.ts.

FieldTypePresenceBehaviour in the handler
session_idstringoptionalOpaque string. Omit and a UUID is generated for you.
image_b64stringone of theseBase64 of a hand image, non-empty. Only path that can reach the IA-03 backend, and only where INFERENCE_URL is configured.
hand_landmarksnumber[][]one of theseAt least 21 points, and the first 21 must each be an [x,y,z] of three finite numbers. Anything shorter or malformed is a 400.

Smallest body that clears validation. The shape is real; the values in angle brackets are placeholders you replace.

curl https://krrrxshxncvcsumugxbi.functions.supabase.co/signs \
  -X POST \
  -H "Authorization: Bearer $VEXKIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
      "session_id": "demo-0001",
      "image_b64": "<base64 of one hand image>"
    }'

Headers

HeaderRequiredDescription
AuthorizationyesBearer <api_key>. The key must carry the signs scope; a key without it is rejected as 401, not 403.
Content-Typeyesapplication/json

No other request header changes behaviour. This page used to document an X-Idempotency-Key; no endpoint reads it, so it has been removed rather than left as a no-op promise.

Response

200 returns the object below. There is no envelope and no wrapper: the fields are top-level.

FieldTypePresenceBehaviour in the handler
signstringrequiredThis endpoint returns `sign`, NOT `state`. Its response is not the Core-5 envelope.
confidencenumberrequiredProbability the classifier assigned to `state` IN THIS REQUEST, rounded to 3 decimals. It is not model accuracy, not a benchmark, and not a quality guarantee. Read `inference` before you trust it.
probabilitiesobjectoptionalPresent only when the real backend returned one. Absent on the heuristic path.
inferencestringrequiredreal = IA-03 answered. real_failed_fallback = IA-03 was configured but failed, so the legacy heuristic answered instead. heuristic = no model was configured at all.
models_usedstring[]requiredEmpty array on every non-real path — nothing ran, nothing is claimed.
costnumberrequired0 on every non-real path.
session_idstringrequiredEchoed back, or the generated UUID.
latency_msnumberrequiredWall time measured inside the function.
model_versionstring | nullrequirednull on the heuristic path — no model version is invented.
timestampstringrequiredISO-8601, generated at response time.
llm_enrichmentobject | nullrequirednull unless VEXKIO_LLM_ENRICH=true on the deployment.

Example values, not a measurement

The field names, types and nesting below are transcribed from the deployed handler. The numbers and strings are placeholders chosen to illustrate the shape. They are not a recorded call, not a benchmark, and not a claim about how any VEXKIO model performs.

In particular confidence is the probability the classifier assigned within a single request. It is not accuracy. VEXKIO publishes no accuracy figure on this site.

example-shape.json
{
  "sign": "hola",
  "confidence": 0.5,
  "inference": "heuristic",
  "models_used": [],
  "cost": 0,
  "session_id": "demo-0001",
  "latency_ms": 12,
  "model_version": null,
  "timestamp": "2026-01-01T00:00:00.000Z",
  "llm_enrichment": null
}

Before you trust a number

  • The heuristic path is a modulo hash over five finger-extension distances, indexed into a fixed 77-word list. It is not a recognition model. Its `confidence` is a hardcoded formula (0.5 when fewer than 21 points arrive; otherwise 0.7 plus fixed bonuses, capped at 0.97) — a constant, not a probability. When `inference` is "heuristic" or "real_failed_fallback", `sign` and `confidence` carry no accuracy claim whatsoever.
  • VEXKIO publishes no accuracy figure for sign-language recognition on this site. The measured numbers that exist in the repo are for a hand-gesture task, not Colombian Sign Language, so quoting them here would be a category error.

Errors

Almost every error body is a JSON object with a single human-readable error string. There is no stable machine-readable code field on these endpoints - branch on the HTTP status, not on the string.

error-shape.json
{ "error": "Provide image_b64 (string) or landmarks (array)" }

The second tab is the one body on these endpoints that does NOT carry an error key. A client that reads only body.error will log undefined for a cost-cap 429, so read the status first. Note the field is retry_after_seconds - seconds, not milliseconds - it appears on this body only, and its value is however many seconds remain until 00:00 UTC, so the number above is just an illustration.

HTTPWhen
400Body is not a JSON object, or a field failed validation. The error string names the field.
401Missing Bearer header, unknown key, revoked key, or a key that lacks this endpoint's scope. All four collapse into the same 401 - a missing scope is NOT a 403 here.
403Organization is suspended. Some non-core endpoints also use 403 for missing consent or attestation flags.
413Body over 12,000,000 bytes, or a base64 field over its own cap (15,000,000 chars for image_b64, 40,000,000 for audio_b64).
429Per-IP throttle, per-org daily limit, monthly session quota exhausted, or a cost cap. See Rate limits below.

Codes this page used to list - invalid_payload, scope_missing, session_not_found, model_unavailable - are not emitted by any handler and have been removed.

Rate limits

Three independent limits can produce a 429. All of them are read from supabase/functions/_shared/rate_limit.ts and the handler itself.

LimitValueScope
Pre-auth throttle60 / minutePer client IP, in-memory, checked before the key is even validated.
Daily request limit10,000 / day (default)Per organization. Resolved from your daily_quota, else your sessions_limit, else the deployment default.
Session quotaper planCumulative sessions used against your plan ceiling. Exhausting it returns 429 until the plan is upgraded.

Two corrections to what this page used to claim. There is no Starter / Pro / Business / Enterprise rps table in force - the tiered limiter exists in the repo but is not imported by any deployed function. And no endpoint emits X-RateLimit-Limit, X-RateLimit-Remaining or X-RateLimit-Reset headers, so do not build a budget on reading them. Retry with your own bounded exponential backoff.

Ready to call it?

Issue a key scoped to signs in the dashboard and run the curl above. $0.07 per session.

Get an API keyRead the quickstart

Product

  • Marketing site
  • Product catalog
  • Dashboard

Docs

  • Quickstart
  • API Reference
  • Status

Company

  • Privacy
  • Terms
  • hello@vexkio.com

Copyright 2026 VEXKIO. All rights reserved.