SYNCHATICA

Conversation API

Conversation API

Conversation API

HTTP API for the private dialogue layer: text, images, voice, per-user memory, a global persona profile per key, and knowledge-driven replies through custom KB.

Single endpointPrivate deploymentPersona profilePer-user memoryKB / RAG

1. Concept

  • One endpoint: POST /api/v1/conversation.
  • Each API key stores one global persona profile for role, style, and positioning.
  • Each user_id under that key gets isolated memory and its own dialogue history.
  • Every rollout runs in a private deployment with its own base URL and isolated execution contour.

2. Endpoint & authentication

The Conversation API runs inside a private deployment. You receive a dedicated base URL and use one endpoint for all dialogue scenarios.

URL

POST https://<PRIVATE_DEPLOYMENT_URL>/api/v1/conversation

Authentication headers

  • Authorization: Bearer YOUR_API_KEY
  • X-API-Key: YOUR_API_KEY
  • Idempotency-Key: optional-request-key

Runtime facts

image limit

≈ 5 MB decoded

voice limit

≈ 25 MB decoded

default key limit

60 RPM

default IP limit

360 RPM

3. Request body

user_id is required. At least one of message, image_b64, or voice_b64 must be present. If both message and voice_b64 are sent, text takes priority while voice remains as extra context.

FieldTypeRequiredDescription
user_idstring (1..128)YesStable identifier of the end user in your own system. It is used as the memory key.
messagestring (1..4000)NoText query. Can be used alone or together with an image.
image_b64base64 stringNoImage without the data: prefix. Supported mimes: image/jpeg, image/jpg, image/png, image/webp.
image_mimestringWith image_b64Image MIME type. If image_mime is present without image_b64, the request is rejected.
voice_b64base64 stringNoVoice input. When message is absent, the service attempts to transcribe audio into text.
voice_mimestringRecommendedSupported values: audio/aac, audio/m4a, audio/mp3, audio/mp4, audio/mpeg, audio/ogg, audio/opus, audio/wav, audio/webm, audio/x-wav.
personaobjectNoUpdates the global persona profile for the API key. Partial fields are merged into the existing profile.

4. Persona profile

persona is the shared profile stored at API-key level. It defines the role, style, and positioning, while the engine keeps individual history per user_id on top of that baseline.

  • Send persona once during initialization or update it partially as the scenario evolves.
  • The global profile is shared across all user_id values under the same key.
  • Memory and dialogue history remain isolated per user_id.
  • role works best as a short operational description of role, knowledge, constraints, and tone — not as a slogan.
FieldTypeDescription
namestring (1..64)Persona name.
ageinteger 1..120Stylistic nuance rather than a business rule.
gendermale | femalePersona gender.
zodiac12 fixed valuesAries..Pisces.
temperamentobjectWeights for sanguine / choleric / phlegmatic / melancholic; normalized inside the engine.
socialityintrovert | ambivert | extrovertBehavioral social vector.
archetypesarray up to 16 enum valuesExamples: Sage, Explorer, Creator, Caregiver.
rolestring (1..1000)Primary working description of role, expertise, constraints, and tone.

5. Response

A successful response contains the generated reply, latency_ms for SLA observation, latency_breakdown for deeper tracing, and request_id for incident tracking.

Response example

{
  "reply": "Basic is usually the best starting point: it covers standard workloads without extra overhead. If you need priority support and a higher request ceiling, Pro is the better fit.",
  "latency_ms": 842,
  "latency_breakdown": {
    "queue_latency_ms": 44,
    "worker_latency_ms": 798,
    "total_latency_ms": 842
  },
  "request_id": "4611686018427387904-7-a1b2c3"
}

6. Errors

All errors use the envelope { detail: { code, message, request_id? } }. request_id may be absent for some early 4xx validation failures.

HTTPcodeDescriptionRetry
401missing_api_keyNo API key provided.No
401invalid_api_keyKey is invalid or deactivated.No
402no_requestsNot enough request balance for API usage.After refill
400invalid_payloadInvalid request shape, missing required field combinations, or broken base64.After fix
400invalid_voice_format / invalid_voice_mime / voice_transcription_failedVoice payload is unsupported, undetected, or could not be transcribed.After fix
409idempotency_in_flight / idempotency_key_reused_with_different_payloadThe idempotency key is already in progress or was reused with a different payload.Carefully
429rate_limited / rate_limited_ipPer-key or per-IP limit exceeded. Retry-After: 60 is returned.Yes
503queue_unavailable / rate_limiter_unavailable / idempotency_unavailableTemporary queue, rate-limiter, or idempotency-storage outage.Yes
504upstream_timeoutWorker or model did not respond in time.Yes
500internal_errorUnexpected internal failure.Yes

7. Request examples

Below are baseline examples for a private deployment. In production you only replace the base URL and the API key.

Request example

{
  "user_id": "usr-42",
  "message": "Help me choose a starter plan and explain how it differs from Pro.",
  "image_b64": null,
  "image_mime": null,
  "voice_b64": null,
  "voice_mime": null,
  "persona": {
    "name": "Nora",
    "gender": "female",
    "sociality": "ambivert",
    "archetypes": ["Sage", "Explorer"],
    "role": "You are the private AI assistant for Acme. You answer product and support questions, rely on the official knowledge base, keep replies concise, and escalate billing disputes to a human."
  }
}

cURL · bash

curl -X POST "https://<PRIVATE_DEPLOYMENT_URL>/api/v1/conversation" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: req-usr-42-001" \
  -H "Content-Type: application/json" \
  -d '{
  "user_id": "usr-42",
  "message": "Help me choose a starter plan and explain how it differs from Pro.",
  "image_b64": null,
  "image_mime": null,
  "voice_b64": null,
  "voice_mime": null,
  "persona": {
    "name": "Nora",
    "gender": "female",
    "sociality": "ambivert",
    "archetypes": ["Sage", "Explorer"],
    "role": "You are the private AI assistant for Acme. You answer product and support questions, rely on the official knowledge base, keep replies concise, and escalate billing disputes to a human."
  }
}'

JavaScript / fetch · ts

const API_URL = 'https://<PRIVATE_DEPLOYMENT_URL>';
const API_KEY = 'YOUR_API_KEY';

const body = {
  "user_id": "usr-42",
  "message": "Help me choose a starter plan and explain how it differs from Pro.",
  "image_b64": null,
  "image_mime": null,
  "voice_b64": null,
  "voice_mime": null,
  "persona": {
    "name": "Nora",
    "gender": "female",
    "sociality": "ambivert",
    "archetypes": ["Sage", "Explorer"],
    "role": "You are the private AI assistant for Acme. You answer product and support questions, rely on the official knowledge base, keep replies concise, and escalate billing disputes to a human."
  }
};

const response = await fetch(`${API_URL}/api/v1/conversation`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': 'req-usr-42-001'
  },
  body: JSON.stringify(body)
});

console.log(response.status, await response.json());

Python / requests · py

import requests

API_URL = 'https://<PRIVATE_DEPLOYMENT_URL>'
API_KEY = 'YOUR_API_KEY'

payload = {
  "user_id": "usr-42",
  "message": "Help me choose a starter plan and explain how it differs from Pro.",
  "image_b64": null,
  "image_mime": null,
  "voice_b64": null,
  "voice_mime": null,
  "persona": {
    "name": "Nora",
    "gender": "female",
    "sociality": "ambivert",
    "archetypes": ["Sage", "Explorer"],
    "role": "You are the private AI assistant for Acme. You answer product and support questions, rely on the official knowledge base, keep replies concise, and escalate billing disputes to a human."
  }
}

resp = requests.post(
    f"{API_URL}/api/v1/conversation",
    headers={
        'Authorization': f'Bearer {API_KEY}',
        'Content-Type': 'application/json',
        'Idempotency-Key': 'req-usr-42-001',
    },
    json=payload,
    timeout=30,
)
print(resp.status_code, resp.json())

8. Custom KB & RAG

The KB is attached to an API key and is automatically applied to all user_id values under that key. At the moment KB is managed outside the HTTP endpoint: you upload JSON and the index is rebuilt in the background.

  • One active knowledge base per API key.
  • KB is not sent in POST /conversation; it acts as the domain layer on top of the persona profile.
  • Expected format: JSON array of objects with text, optional id, optional category, and tags[].
  • Actual retrieval uses semantic search and blends the relevant fragments into the generated reply.

KB JSON example

[
  {
    "id": "faq-billing-1",
    "category": "support",
    "tags": ["billing", "how do I pay", "refund", "plan"],
    "text": "Payment is processed after order confirmation. If the issue is about refunds or disputed charges, collect context first and hand the case to a human."
  },
  {
    "id": "faq-plan-basic",
    "category": "sales",
    "tags": ["basic", "starter plan", "getting started"],
    "text": "Basic is the right entry plan for first rollout and standard workload. Explain the scenario first, then compare Basic and Pro briefly in terms of limits and support."
  }
]

Need a private deployment for your product?

We can map how Synchatica should be deployed into your contour, which persona and KB fields to define, and where moderation, handoff, and request tracing make sense.