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¶
- Request
GET /agents/{id}. Read theETagresponse header and completeagentandoptionsobjects. - Change only
options.systemPromptin the retrieved configuration. The PUT body containsagentandoptions, without the outeridorrevisionresponse fields. - Send PUT to the same path with
Content-Type: application/jsonandIf-Matchcontaining the complete ETag from step 1. - 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:
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.