Skip to content

API examples

These examples call https://app.nuvoca.ai/api/external/v1 using an API key or REST OAuth access token with the listed scopes.

Load NUVOCA_ACCESS_TOKEN from protected credential storage. Keep its value out of scripts, shell history and HTTP logs.

Verify connection and selections

Scopes: connection:verify, agents:read, agents:configuration:read.

curl --fail-with-body --silent --show-error \
  --header "Authorization: Bearer ${NUVOCA_ACCESS_TOKEN}" \
  "https://app.nuvoca.ai/api/external/v1/connection"

curl --fail-with-body --silent --show-error \
  --header "Authorization: Bearer ${NUVOCA_ACCESS_TOKEN}" \
  "https://app.nuvoca.ai/api/external/v1/agent-catalog"

curl --fail-with-body --silent --show-error \
  --header "Authorization: Bearer ${NUVOCA_ACCESS_TOKEN}" \
  "https://app.nuvoca.ai/api/external/v1/agent-catalog/voices?language=en&page=0&size=25"

Check the workspace name and granted scopes. Copy a permitted model and suitable voiceId from the catalogs. A credential without connection:verify can still use its other authorized operations.

Create a disabled voice Agent

Additional scope: agents:write. Save this example as agent.json. GPT_4_1_MINI and azure:FLORIAN_HD are example values; replace them if not selectable in your catalog. Use synthetic test data.

{
  "agent": {
    "enabled": false,
    "agentType": "VOICE",
    "title": "NuvoCar reception draft",
    "agentName": "NuvoCar Assistant",
    "sttProvider": "AZURE",
    "sttLanguages": ["en-US"],
    "voiceId": "azure:FLORIAN_HD",
    "timezone": "Europe/Berlin",
    "greetingMorningText": "Good morning, this is NuvoCar's digital assistant. How can I help?",
    "greetingAfternoonText": "Hello, this is NuvoCar's digital assistant. How can I help?",
    "greetingEveningText": "Good evening, this is NuvoCar's digital assistant. How can I help?",
    "initialSilenceTimeoutMs": 1500,
    "segmentationSilenceTimeoutMs": 500,
    "phraseList": ["NuvoCar"]
  },
  "options": {
    "model": "GPT_4_1_MINI",
    "systemPrompt": "You are NuvoCar's digital receptionist. Ask about the caller's request. Never invent prices or appointments. Explain when information is unavailable. Never claim storage or transfer without a successful configured action.",
    "conversationHistoryLimit": 20,
    "knowledgeBaseId": null,
    "ragTopK": 5,
    "ragSimilarityThreshold": 0.5,
    "temperature": 0.3,
    "maxTokens": 1000,
    "ttsStreamingMode": "QUALITY_SSML",
    "queryTransformEnabled": false,
    "queryTransformHistoryLimit": 5,
    "queryTransformConfidenceThreshold": 0.8,
    "queryTransformMode": "LLM"
  }
}
curl --fail-with-body --silent --show-error \
  --request POST \
  --header "Authorization: Bearer ${NUVOCA_ACCESS_TOKEN}" \
  --header "Content-Type: application/json" \
  --data-binary @agent.json \
  "https://app.nuvoca.ai/api/external/v1/agents"

The response returns the Agent ID and revision. The draft has no phone number or assigned tools. It does not start a call. Complete and test the Agent configuration before production use.

Update a prompt without overwriting concurrent changes

  1. Request GET /agents/{id}. Read the ETag response header and complete agent and options objects.
  2. Change only options.systemPrompt in the retrieved configuration. The PUT body contains agent and options, without the outer id or revision response fields.
  3. Send PUT to the same path with Content-Type: application/json and If-Match containing the complete ETag from step 1.
  4. After 409, read again and reconcile your proposal. Do not blindly apply the new ETag to the old body.
PUT /api/external/v1/agents/AGENT_ID
Authorization: Bearer REST_ACCESS_TOKEN
Content-Type: application/json
If-Match: "REVISION_FROM_GET"

Replace the placeholders in this header example. An Agent revision is a composite value; treat it as an opaque string and do not calculate it yourself.

Upload a knowledge file

Scopes: knowledge-bases:read, knowledge-bases:write, documents:read, documents:write. First create a knowledge base using POST /knowledge-bases with this body:

{"title": "NuvoCar service knowledge"}

Set NUVOCA_KB_ID to the returned ID. Then upload the reviewed local file:

curl --fail-with-body --silent --show-error \
  --request POST \
  --header "Authorization: Bearer ${NUVOCA_ACCESS_TOKEN}" \
  --form-string "title=Service knowledge" \
  --form "file=@servicewissen.md;type=text/markdown" \
  "https://app.nuvoca.ai/api/external/v1/knowledge-bases/${NUVOCA_KB_ID}/documents"

Do not set the multipart content type manually; the client adds the boundary. Assign the knowledge base to an Agent through options.knowledgeBaseId; this additionally requires Agent configuration read and write permissions. Test real knowledge questions before using the collection in production.

Read summaries for a local day

Scope: call-summaries:read. This fixed example selects 2 November 2026 in Europe/Berlin, from midnight inclusive to midnight the next day exclusive. Both bounds use UTC+1 on this date.

curl --fail-with-body --silent --show-error --get \
  --header "Authorization: Bearer ${NUVOCA_ACCESS_TOKEN}" \
  --data-urlencode "from=2026-11-02T00:00:00+01:00" \
  --data-urlencode "to=2026-11-03T00:00:00+01:00" \
  --data-urlencode "page=0" \
  --data-urlencode "size=100" \
  "https://app.nuvoca.ai/api/external/v1/call-summaries"

For “today”, compute both local midnight boundaries using the IANA timezone, then convert them to ISO timestamps. Do not hard-code the day's duration or a year-round offset. URL encoding correctly preserves the plus sign in an offset.

Increase page until all totalPages are retrieved. Honor Retry-After after 429. Results include phone numbers and potentially personal information; retain or log them only for the intended purpose. Review selection and redaction rules before drawing conclusions from missing results. Find a suitable analysis instruction under Review callback needs.