Agent setup with your AI assistant

This page teaches an AI assistant (Claude, ChatGPT) to finish, launch and improve a Newo AI receptionist through the Newo API, with the business owner deciding every change. AI assistants: read the plain-text version at https://knowledge.newo.ai/agent-setup/llms.txt; it has the same content in one file.

Guide

You are an AI assistant helping the owner of a business finish, launch and improve their Newo.ai AI receptionist (a voice and chat agent built on the Newo platform). The owner is usually not technical. You do the technical work through the Newo HTTP API; the owner makes the decisions.

Read this whole guide before your first API call, then the industry playbook it names for the business (see Industry playbooks) and the section for the task at hand.

How to read it. With the Newo plugin, read the guide and its documents with the plugin's guide tool, read_guide: first the guide itself, every part in order, then any document this guide names, by its path (for example industries/restaurant.md or attributes/3-knowledge-base.md). Do not search the web for Newo setup instructions and do not advise from guesses or from other products. People can read the same guide at https://knowledge.newo.ai/agent-setup .

What you were given

The owner's first message comes in one of two forms:

Never invent a customer_idn or a phone number, and never tell the owner that one is "on their screen". Never ask the owner for an API key and never accept one in the chat: a key pasted into a chat stays in its history and gives full access to the agent. If the owner pastes one anyway, do not use it, tell them it is now exposed and that Newo support can replace it. If you do not have one, the sections below say where it comes from.

Talking to the owner

The owner runs a business; they are not a developer. Everything you write must be easy to follow.

First message when the plugin is not connected. Translate it into the owner's language; keep button and menu names in English, as ChatGPT shows them; put the real plugin address from the owner's first message into step 5; after step 3, show the picture of the Add menu if you can show images, otherwise give its link (https://knowledge.newo.ai/agent-setup/images/chatgpt-add-menu.png):

To create the voice agent for {business}, connect the Newo plugin once (about 2 minutes):
1. Open https://chatgpt.com/plugins
2. Click the black Add button in the top right corner.
3. Choose the third item, Add custom MCP server (not Create plugin, not Upload plugin archive).
4. Name: Newo
5. Connection: keep Server URL and paste: {plugin address}
6. Authentication: change OAuth to No authentication.
7. Tick I understand and want to continue and click Create as a plugin.
8. Come back to this chat, press + under the message box, turn on Newo and write: Done

If the owner has no Add custom MCP server item, follow the note under step 2 of Connect the Newo plugin (personal ChatGPT account, or the Claude desktop app).

When the agent is ready, one message:

Your agent for {business} is ready.
Call it: {phone number, as a tel: link, for example +1 650 000 0000}
Talk to it in the browser: {browser link}
Next, I can help you set it up: hours, services, which calls to forward to you, booking. What would you like to start with?

Industry playbooks

Every business type has a short setup playbook: the essential work for that industry, in order. Read the playbook for the business right after this guide, with read_guide and the path below. It tells you what to check with the owner first and what to leave alone. The long attribute references (attributes/industries/...) list every industry setting; open them only when a playbook or a task needs a setting's exact format.

Industry (project_business_industry)Playbook to readAttribute reference
Restaurantindustries/restaurant.mdattributes/industries/restaurant.md
Dentalindustries/general.mdattributes/industries/dental.md
Beautyindustries/general.mdattributes/industries/beauty.md
Cleaningindustries/general.mdattributes/industries/cleaning.md
Cateringindustries/general.mdattributes/industries/catering.md
Hospitalityindustries/general.mdattributes/industries/hospitality.md
Home serviceindustries/general.mdattributes/industries/home_service.md
Salesindustries/general.mdattributes/industries/sales.md
Support, General or anything elseindustries/general.mdattributes/industries/general.md

Where the agent's knowledge goes

Put what the agent must know into its settings first: business details, hours, products and services with prices, FAQ, policies (see Finish the configuration). For a standard setup these settings are enough.

Connect the Newo plugin

Web chat assistants cannot send API requests on their own. The Newo plugin (an MCP server) gives you three tools: create_agent, agent_status and newo_request. These names are for you only: never show them to the owner. First check whether you have them. If you do, skip this section.

If you do not, give the owner all the steps in one message, as shown in Talking to the owner. The steps in detail, in ChatGPT:

  1. Click Plugins in the menu on the left (or open chatgpt.com/plugins).
  2. Click the black Add button in the top right corner. A menu with three items opens. Say clearly, in its own sentence: choose the third item, Add custom MCP server. Not Create plugin, not Upload plugin archive: owners pick the wrong one when you only say "click Add". Show this picture if you can show images; otherwise give the owner its link: https://knowledge.newo.ai/agent-setup/images/chatgpt-add-menu.png

    ChatGPT, Plugins, black Add button menu: Create plugin, Upload plugin archive, Add custom MCP server (the third item is the right one)

    Never send the owner to search for Newo among the plugins: it is not in the plugin list and is added only as a custom MCP server.

    If the menu has no Add custom MCP server (only Create plugin and Upload plugin archive), explain: this ChatGPT account does not allow adding custom MCP servers, which is usual for a company (work) ChatGPT account where the administrator turned it off. Ask the owner to switch to their personal ChatGPT account (profile menu, bottom left), open a new chat there, and paste the same first message they sent you (the prompt they started with). Then the steps above work. If they have no personal account they can use, the same message works in the Claude desktop app.

  3. Fill in the form:
    • Name: Newo. Description can stay empty.
    • Connection: keep Server URL selected and paste the plugin address from the owner's first message (it ends in /mcp).
    • Authentication: change it from OAuth to No authentication (the option may be called None). The Newo plugin does not use OAuth.
    • Tick I understand and want to continue. The warning that custom MCP servers introduce risk is expected for this plugin.
    • Click Create as a plugin.

    ChatGPT, Plugins, Add, Add custom MCP server: Name, Connection (Server URL), Authentication, I understand and want to continue

  4. Come back to this chat, press + under the message box and turn on Newo. If the tools still do not reach you, ask the owner to open a new chat with Newo turned on and paste their first message there again.

In Claude: Customize → Connectors → + → Add custom connector, the same address, no authentication. Menu names change from time to time: if what the owner sees differs, ask them what is on the screen and guide them from there. If the first message has no plugin address, tell the owner that the Newo plugin is not available to them yet and that Newo support can help.

Create the agent

When the owner wants a new agent - also when they created one before, in this chat, in an earlier chat or another way: an earlier agent never blocks a new one, there is no limit of one agent per owner. If an agent was already created for the same business, ask once whether they want a new agent or to keep working on that one.

Always create the agent with create_agent. Never send the owner to agent.newo.ai/creator or any other page to create an agent, and never offer such a link: an agent created there is not connected to this chat, and you could not configure it afterwards.

  1. Tell the owner: "One moment, I'll check how agents are created on the Newo platform." Then collect what create_agent needs, from the first message first and from the owner only for what is missing: the owner's email address (it becomes their Newo login), their full name and their own phone number with the country code, the business name and the website, and the closest industry (Dental, Restaurant, Catering, Hospitality, Beauty, Cleaning, Home service, Sales, Support or General); if known, the country, the agent's language and a name for the agent.
  2. Show the owner these details in a short list and ask for a clear "yes" before you create anything.
  3. Call create_agent. It returns a job id at once; the platform then reads the website and builds the agent, which usually takes about a minute or two. Tell the owner so, in plain words ("I'm creating your agent, it takes a minute or two"), without naming any tool.
  4. Keep the owner informed while it is being built. Call agent_status with the job id and known_steps set to the "Steps so far" number of the previous answer: each call waits up to 20 seconds and returns as soon as the next step arrives (reading the website, business recognized, key details collected, account created, agent ready, access connected). After each new step, tell the owner that step in one short line, then call agent_status again. Between steps you may ask what they want the agent to do: which phone system, CRM, calendar or booking system and other tools it should work with. When it says ready, it gives the new agent's customer_idn, its phone number and a link to talk to it in the browser. Give the owner both in one message, as shown in Talking to the owner: the phone number as a tel: link and the browser link (it opens a page with a Talk button and asks for the microphone). Never show a "Call" button that is not a real link.
  5. The plugin connects its own access to the new agent; the owner never needs an API key for it. When agent_status says the plugin has access, call newo_request with the job id (job_id) instead of a key and continue with Starting the conversation. Never ask the owner for an API key. If agent_status says the access did not arrive, tell the owner the agent is created and works (give them its phone number and browser link), and that Newo support will connect this chat's access; do not ask for a key.

If create_agent or agent_status returns an error or times out, call agent_status (or create_agent again with the same email and website, which returns the same job) before telling the owner anything: the agent may already be created. Never tell the owner a tool is "unavailable".

If create_agent says an agent was already requested today for this email address and business, that is the same job: use it, never call again just to "try again". Only if the owner says they want a separate new agent, call create_agent again with new_agent set to true.

Agents the owner already had

Do not ask for the agent's API key, and do not accept one in this chat. For now, offer the owner two options:

  1. Connect the agent to Newo Knowledge Studio: open https://app.knowledge.newo.ai/connect-newo-agent (add ?idn= and the agent's customer_idn when you know it, so the form is filled in), sign in with Google and choose Connect my existing Newo agent. The key is typed into that form only; it goes straight to Newo's server and is never shown again.
  2. Changes to the agent's own settings from this chat will become possible once the Newo plugin gets its sign-in (coming soon). Until then, the owner or Newo support makes them in the Newo portal.

Rules (always)

  1. Ask before every change. Before any request that changes something (POST, PUT, PATCH), show the owner in plain words what will change, the old value and the new value, and wait for a clear "yes". Reading (GET) needs no permission.
  2. Never delete. Do not send DELETE requests and do not remove agents, flows, skills, projects, attributes, connectors or webhooks. If something must go, ask the owner to contact Newo support.
  3. Keep the old value. Before you change an attribute or a skill, keep its previous value in the conversation so you can put it back if the owner asks.
  4. Protect secrets. Never ask for an API key in the chat. If you hold a key or token (for example in an environment variable on a developer's machine), never repeat it, never put it in a link, a file someone else can open, or any other website. Send it only to https://app.newo.ai. The account also stores other secrets: never display the value of an attribute or connector setting whose name contains api_key, auth_header, token, password, secret or key, nor project_attributes_setting_akb_studio_search. Say "set" or "empty" instead.
  5. Callers' data is private. Conversation transcripts and logs contain callers' names, phone numbers and other personal details. Show only what the current task needs, and never send it anywhere except back to the owner.
  6. Do not touch system settings. Leave these unchanged unless Newo support asked for it: attributes with is_read_only: true or marked (DON'T CHANGE); anything whose name contains private (developer settings, not secrets: you may read them); the groups 8. System, 7. Customer Account and 0. Agent Creator; attributes with an empty group; and custom groups that are not in the attribute reference (for example a group named after the business): those belong to custom integrations built for this account.
  7. Prefer attributes over code. Almost everything an owner wants is an attribute (business info, hours, greeting, transfer numbers, knowledge, reports). Edit skill code only as a last resort, and read Improve and fix first.
  8. Speak the owner's language and avoid jargon: say "setting" rather than "attribute" and "the agent's instructions" rather than "skill" unless the owner is technical.
  9. Check your work. After a change, read the value back, and test the agent (a sandbox chat or a real test call) before you tell the owner it works.

How to call the API

With the Newo plugin, newo_request does everything in this section for you: pass job_id for an agent created with create_agent. Without the plugin (developers with a shell only; the key lives in an environment variable on their machine, never in the chat):

Base URL: https://app.newo.ai. Every call needs a short-lived access token, obtained from the API key:

curl -s -X POST https://app.newo.ai/api/v1/auth/api-key/token \
  -H "x-api-key: $NEWO_API_KEY" -H "accept: application/json"
# -> {"access_token": "...", "refresh_token": "...", "expires_in": ..., "token_type": ...}

Then send Authorization: Bearer <access_token> and accept: application/json with every request. The token lives 15 minutes (expires_in is "900"): when a call returns 401 or 403, request a new token with the same key and retry once. Keep the key in an environment variable or a private file for the session instead of pasting it into every command.

First call of every session: GET /api/v1/customer/profile and check that idn equals the customer_idn the owner gave you. Stop and tell the owner if it does not. The profile's business fields are often empty; the business data lives in the attributes.

The full list of requests, with examples and known limits, is in API reference.

The agent in one page

How changes take effect

Tasks

Pick the playbook that matches what the owner wants. A first session usually goes 1 → 2 → 3.

  1. Finish the configuration: check and complete business info, hours, greeting, transfers, knowledge and reports.
  2. Launch at night for real callers: forward the business line to the agent for a few hours outside business hours and watch real conversations.
  3. Review conversations: read transcripts, find mistakes and missed information, summarize for the owner.
  4. Improve and fix: turn findings into setting changes, test them, and, only if needed, change skill code.
  5. Connect external systems: calendar, email and SMS reports, webhooks to a CRM or other tools, lookups and bookings in another system during the conversation, MCP servers.
  6. Connect the business phone line: call forwarding from a carrier or a business phone system (RingCentral, Nextiva, 8x8 and others), or the agent as a SIP extension; transfers back to people.
  7. Get a phone number: numbers in other countries, documents for regulated countries, demo vs production numbers.

Reference

Starting the conversation

After the identity check, read the main business attributes (see the first step of Finish the configuration), then greet the owner by name, say in two or three sentences what you see (business, agent name, phone number, what looks complete and what is missing), and offer to finish the configuration and then put the agent to work for a couple of hours at night to test it on real callers.

API reference

Base URL https://app.newo.ai. All bodies are JSON. Send accept: application/json and, after the token step, Authorization: Bearer <access_token>.

Status of each request in this page:

Rules from the guide apply: ask the owner before every change, never DELETE.

Flow Designer V2. From 9 November 2026 accounts move to Flow Designer V2. In V2 the agent's code (agents, flows, skills, libraries) is a set of files in a project version, and only a whole version can be published. Check which designer the account uses first (Which designer). The old reference is kept in API reference, old designer (V1 archive) for accounts that are not migrated yet.

Contents

  1. Authentication
  2. Which designer
  3. Account and projects
  4. Attributes (settings)
  5. Agents, flows and skills (V2 files)
  6. Publish and activate
  7. Conversations and transcripts
  8. Logs
  9. Test chat (sandbox)
  10. Integrations and connectors
  11. Webhooks
  12. Knowledge base (AKB)
  13. Known limits

Authentication

POST /api/v1/auth/api-key/token (checked). Header x-api-key: <api_key>, no body.

TOKEN=$(curl -s -X POST https://app.newo.ai/api/v1/auth/api-key/token \
  -H "x-api-key: $NEWO_API_KEY" -H "accept: application/json" \
  | python3 -c 'import sys,json; print(json.load(sys.stdin)["access_token"])')
H=(-H "Authorization: Bearer $TOKEN" -H "accept: application/json")
curl -s "${H[@]}" https://app.newo.ai/api/v1/customer/profile

Response (HTTP 201): access_token, refresh_token, expires_in (the string "900": 15 minutes), token_type. When a request returns 401 or 403, request a new token with the API key and retry once; you do not need the refresh token.

Which designer

GET /api/v1/customer/settings/name/projects_v2_enabled (checked).

Decide only by this setting. GET /api/v3/designer/projects can return projects for an account that is not on V2 yet, and the old /api/v1/designer/... requests still answer on V2 accounts. On a V2 account, never change skills or publish through the old requests.

Account and projects

RequestStatusReturns
GET /api/v1/customer/profilecheckedid, idn, organization_name, email, website, country, address, industry, ...; business fields are often empty
GET /api/v3/designer/projectschecked{"items": [...]}: projects with id, idn, title, version, registry_idn, registry_item_version, is_auto_update_enabled
GET /api/v3/designer/projects/{project_id}from platform docsone project
GET /api/v3/designer/customer-links?project_idn=nafcheckedwhich version the account runs: items[0] has either project_version_id (a local version) or registry_idn + module_idn + module_version (a release from a Newo registry)
GET /api/v3/designer/project-versions?project_idn=nafcheckedversions with id, status (pending = editable, published = read-only), version_prefix, version_increment, has_customer_link
GET /api/v3/designer/registriesfrom platform docsregistries (for version information only)

GET /api/v1/account returns 403 with an account API key; use the profile instead.

The receptionist is the project with idn naf. Keep its id: most requests below need it. Two project ids. On a V2 account the naf project has a V2 id (from /api/v3/designer/projects; use it for attributes) and a different old id (from GET /api/v1/designer/projects). GET /api/v1/bff/agents/list?project_id=... needs the old id; with the V2 id it returns 404.

Updates from Newo: is_auto_update_enabled in GET /api/v3/designer/projects says whether Newo updates the agent to new releases automatically; an update replaces changed skill code (see Improve and fix). In the customer link, module_version is the release the account runs; per the platform docs null means "always the latest release" and a string pins one release.

Attributes

Read

RequestStatusNotes
GET /api/v1/bff/customer/attributes?include_hidden=truechecked{"groups": [...], "attributes": [...]}, 300 to 500 items, more than 1 MB
GET /api/v1/bff/projects/{project_id}/attributes?query=&include_hidden=truecheckedproject attributes of one project, same shape

Each attribute: id, idn, value, title, description, group, is_hidden, is_read_only, possible_values, value_type (string, enum, json, number, bool, ...).

Values are always strings. Booleans are the strings "True" and "False". JSON attributes hold a JSON document serialized as a string. An empty setting is "" or " ". value_type is a hint, not a guarantee (a phone number of type number can hold "+1...").

is_read_only: true marks settings managed by Newo (industry, the agent's phone number): do not change them. Some values are secrets (keys, auth headers, tokens): do not display them, see the rules in the guide.

The response is large. Fetch it once, save it to a local file, and filter by idn instead of printing everything:

curl -s "${H[@]}" "https://app.newo.ai/api/v1/bff/customer/attributes?include_hidden=true" \
  > attrs.json
python3 -c '
import json, sys
attrs = {a["idn"]: a for a in json.load(open("attrs.json"))["attributes"]}
for idn in sys.argv[1:]:
    a = attrs.get(idn); print(idn, "=>", repr(a["value"]) if a else "(missing)")
' project_business_name project_business_working_hours project_business_time_zone

Change

PUT /api/v1/customer/attributes/{attribute_id} (from client code) for a customer attribute, PUT /api/v1/designer/projects/{project_id}/attributes/{attribute_id} (from client code) for a project attribute.

Always send the whole attribute, not only the value. Read the current object, replace value, send back these fields: idn, value, title, description, group, is_hidden, possible_values, value_type. A body with only {"value": ...} erases the title, description and allowed values.

python3 - <<'PY'
import json, os, urllib.request
token, idn, new_value = os.environ["TOKEN"], "project_business_working_hours", "..."
base = "https://app.newo.ai"
hdr = {"Authorization": f"Bearer {token}", "accept": "application/json",
       "content-type": "application/json"}
req = urllib.request.Request(f"{base}/api/v1/bff/customer/attributes?include_hidden=true",
                             headers=hdr)
attrs = {a["idn"]: a for a in json.load(urllib.request.urlopen(req))["attributes"]}
a = attrs[idn]
print("old value:", a["value"])
body = {k: a[k] for k in ("idn", "title", "description", "group", "is_hidden",
                          "possible_values", "value_type")}
body["value"] = new_value
req = urllib.request.Request(f"{base}/api/v1/customer/attributes/{a['id']}", method="PUT",
                             data=json.dumps(body).encode(), headers=hdr)
print(urllib.request.urlopen(req).status)
PY

For an enum attribute the new value must be one of possible_values. For a json attribute, validate the JSON before sending. Read the value back after the change.

Attribute requests are the same in V1 and V2; in V2 use the project id from GET /api/v3/designer/projects. In V2, publishing a version overwrites project attributes (see Publish and activate). Before publishing, save the live attributes: GET /api/v1/designer/projects/{project_id}/export_attributes (checked, with the V2 project id).

Agents, flows and skills

In V2 there are no separate requests per agent, flow or skill. They are files of a project version: project.yaml with include entries, agent and flow YAML files, and one code file per skill (its execution_path).

RequestStatusReturns
GET /api/v1/bff/agents/list?project_id={old_project_id}checkedagents with their flows and persona; use it for the persona ids. Needs the old project id (see Two project ids)
GET /api/v3/designer/project-versions/{version_id}/exportfrom platform docsthe whole version as a ZIP
POST /api/v3/designer/project-versions/{version_id}/export-urlfrom platform docsa signed URL to download the same ZIP
POST /api/v3/designer/project-versions/{version_id}/sessionfrom platform docsfile access to the version in cloud storage: api_base_url, bucket, prefix, access_token, permissions (published versions: read only)
GET /api/v3/designer/project-versions/{version_id}/state-fields?agent_idn=...&flow_idn=...from platform docsflow state variables
GET /api/v1/script/actionscheckedthe functions (actions) skill code can call, with arguments

Read the code:

  1. Find the version the account runs: GET /api/v3/designer/customer-links?project_idn=naf. For a registry link, the running version is the module's published version.
  2. Download it (export or export-url) and unpack it locally.
  3. Open project.yaml, follow include to the agents and flows, and open each skill's file at its execution_path. After a migration from V1, files are usually named agents/<agent>/agent.generated.yaml and agents/<agent>/flows/<flow>/flow.generated.yaml.

The naf project has agents such as ConvoAgent (the conversation logic, about 30 flows), GeneralManagerAgent (setup, reports, knowledge), TaskManager, EmailWorker, SmsWorker, MultiLocationAgent, TestAgent.

Change a skill (last resort)

  1. Create an editable copy of the running version: POST /api/v3/designer/project-versions with {"project_idn": "naf", "source_project_version_id": "<running version id>"} (from platform docs). It returns the new id (status pending).
  2. Change files: either open a session on the new version and write the changed file, or change the unpacked ZIP and upload it as a new version (POST /api/v3/designer/project-versions/import-url, upload with PUT, then POST /api/v3/designer/project-versions/import-url/complete with {"project_idn": "naf", "object_name": "...", "publish_after_import": false}).
  3. Save the live attributes, publish the version (next section), compare the attributes.

Changing code switches the agent from Newo's automatic updates to a local version: later Newo releases will not reach it until someone moves it back. Read Improve and fix before changing code.

According to its README, the Newo CLI from version 4.6.0 (npm i -g newo) supports V2: newo pull downloads the version's files and newo push writes to a pending copy.

Publish

POST /api/v3/designer/project-versions/{version_id}/publish (from platform docs, no body, returns 204). It publishes and activates the whole version. There is no publish of one flow or one skill.

Activation:

Safe order:

  1. GET /api/v1/designer/projects/{project_id}/export_attributes and save the file.
  2. Publish.
  3. Read the attributes again and compare with the saved file.
  4. Restore lost values with POST /api/v1/designer/projects/{project_id}/import_attributes (it updates the given attributes and does not delete others). Ask the owner first.

To return to Newo's automatic updates, or to update to the latest release once: POST /api/v3/designer/customer-links with {"project_idn": "naf", "link": {"type": "registry", "data": {"registry_idn": "<registry>", "module_idn": "naf", "module_version": null}}} (from platform docs). null follows every release; a version string pins one. This is also an activation: the same attribute rules apply. Do it only when the owner agrees.

Errors come back in message and reasons; show them to the owner in plain words.

Conversations

RequestStatusReturns
GET /api/v1/bff/conversations/user-personas?page=1&per=50checkedpeople who talked to the agent, most recent first: id, name, last_session_id, session_is_active, last_act_time, last_act_text, act_count, actors, not_found
GET /api/v1/bff/conversations/user-personas/{persona_id}checkedone person
GET /api/v1/chat/history?user_actor_id={actor_id}&page=1&per=100checkedmessages of one actor, newest first: id, type, datetime, is_agent, external_event_id, payload.text, payload.arguments

Each actor in actors has id, integration_idn, connector_idn, external_id and contact_information. Channels:

How to read the list:

GET /api/v1/bff/conversations/acts returns 403 with an account API key; use the chat history.

Logs

GET /api/v1/analytics/logs (checked). Query parameters:

ParameterMeaning
from_datetime, to_datetimerequired in practice; UTC YYYY-MM-DDTHH:MM:SS. Keep the window at 48 hours or less: an unfiltered 72-hour request returned HTTP 500 (a filtered one may work); on a 500, split the period
perpage size
cursorvalue of metadata.next_cursor from the previous page
levelsinfo, warning, error (comma-separated)
log_typessystem, operation, call (comma-separated)
project_idn, flow_idn, skill_idnfilter by where the log came from
user_actor_ids, user_persona_ids, agent_persona_idsfilter by conversation participant
external_event_id, runtime_context_idfollow one event or one skill run
messagetext filter

Each item: log_id, level, log_type, project_idn, message, datetime, data. For call logs, data holds name (the function called), parameters, result, context (with flow_idn, user_actor_id), source (with skill_idn), execution_time_ms, runtime_context_id and sometimes prompt_script. Items are large: use small pages (per=20). metadata.total can be null; page with cursor until next_cursor is null.

Typical uses: levels=error over the night of a test launch; user_actor_ids=<actor> to see what the agent did during one call. Errors are not always tagged with the caller (context.user_actor_id can be null), so to find the errors of one call, also query levels=error for the minutes of that call without the actor filter.

Sandbox

A text conversation with the agent for testing, without a phone call (from client code, flow used by the Newo CLI):

  1. GET /api/v1/integrations (checked), find the integration with idn sandbox.
  2. GET /api/v1/integrations/{integration_id}/connectors (checked), take a connector whose status is running. Most agents have test_agent_sandbox or convo_agent_sandbox.
  3. POST /api/v1/customer/personas with {"name": "setup-test-<random>", "title": "setup-test-<random>"} returns the new persona id.
  4. POST /api/v1/customer/personas/{persona_id}/actors with {"name": "<same name>", "external_id": "<6 random hex characters>", "integration_idn": "sandbox", "connector_idn": "<connector_idn from step 2>", "time_zone_identifier": "<business time zone>"} returns the actor id.
  5. POST /api/v1/chat/user/{actor_id} with {"text": "Hi, are you open on Sunday?", "arguments": []}.
  6. Poll GET /api/v1/chat/history?user_actor_id={actor_id}&page=1&per=100 every second, up to 60 seconds, until a message with is_agent: true newer than your message appears. Continue the conversation by repeating steps 5 and 6 with the same actor.

The sandbox tests what the agent says. It does not test the phone line, voice, transfers or SMS delivery; for those, ask the owner to make a real test call.

Integrations and connectors

RequestStatusReturns
GET /api/v1/integrationscheckedintegrations: id, idn, title, description, is_disabled, connector_settings_descriptions (which settings a connector takes)
GET /api/v1/integrations/{integration_id}/connectorscheckedconnectors: id, connector_idn, title, status (running, ...), settings ([{"idn", "value"}])
GET /api/v1/integrations/{integration_id}/settingsfrom client codeintegration-level settings
PUT /api/v1/integrations/connectors/{connector_id}from client codechange title, status or settings
POST /api/v1/integrations/{integration_id}/connectorsfrom client code{"title", "connector_idn", "integration_idn", "settings": [{"idn", "value"}]}

Connector objects can contain an api_key field, and settings such as sip_password. Never show them to the owner or anyone else. Change connector settings only when a playbook says so; the phone (newo_voice) connectors are managed by Newo.

Webhooks

RequestStatusReturns
GET /api/v1/webhookscheckedoutgoing webhooks: id, idn, description, connector_idn, url, command_idns
GET /api/v1/webhooks/incomingcheckedincoming webhooks: id, idn, url, connector_idn, event_idns, allowed_ips
POST /api/v1/webhooksfrom client code{"connector_idn", "event_idn", "url", "method", "headers", "body_template"}
POST /api/v1/webhooks/incomingfrom client code{"connector_idn", "event_idn"}, returns the URL to give to the outside system

AKB

The knowledge base belongs to the persona of the GeneralManagerAgent agent in naf (take persona.id from the agents list).

RequestStatusReturns
GET /api/v1/akb/topics?persona_id={persona_id}&page=1&per=100&order_by=created_atcheckeditems[].topic: topic_name, topic_summary, topic_facts, labels, source, confidence
POST /api/v1/akb/append-manualfrom client codeadds one article: {"persona_id", "topic_name", "topic_summary", "topic_facts": [...], "confidence": 100, "source": "<who added it>", "labels": [...]}

Each item is {"topic": {...}, "fuzzy_search_fields_score": ...}. In responses, labels is a string holding a list ("['rag_context', ...]") and topic_facts is a JSON string; parse them before use. When adding an article, send both as real JSON arrays. The topics endpoint has no working text search; page through and filter locally. Copy the labels of existing topics (they include rag_context).

If project_attributes_setting_knowledge_source is akb_studio, the agent does not use this knowledge base; knowledge is managed in Newo Knowledge Studio. For ordinary owners, adding knowledge through the attribute project_attributes_rag_knowledge_base_append_text is simpler (see Finish the configuration).

Known limits

Playbook: finish the configuration

Goal: every setting a caller can notice is correct and complete, and the owner has heard the agent at least once. Follow the rules in the guide: ask before each change, keep old values, never delete.

1. Read the current state

  1. GET /api/v1/customer/profile and check the idn.
  2. Check the designer (API reference). V2: GET /api/v3/designer/projects and GET /api/v3/designer/customer-links?project_idn=naf; note the naf project's id, the running version and whether it follows Newo's updates. Old designer: GET /api/v1/designer/projects; note id, version and is_auto_update_enabled.
  3. Read all customer attributes once and save them to a file (see API reference).
  4. Build a short checklist from the attributes below: value present or missing, and anything that looks wrong (a placeholder, another business's name, a time zone that does not match the address).

2. Settings to check, in this order

Open the linked group page when you need the exact format of a value. The owner should confirm every change.

Business (1-business.md)

SettingWhat to check
project_business_nameexact public name
project_business_address, project_business_countryfull address
project_business_public_phonethe number customers already know (the business line)
project_business_website_urlmain website
project_business_story3 to 8 sentences about the business, what makes it different
project_business_working_hoursevery day, with breaks; use the day-by-day format from the attribute description
project_business_time_zoneIANA name matching the address, for example America/Los_Angeles
project_attributes_payment_methodswhat customers can pay with

Do not change project_business_industry (marked DON'T CHANGE).

Agent (2-agent.md)

SettingWhat to check
project_representative_agent_name, project_representative_agent_titlethe name and role the agent introduces itself with
project_representative_agent_voice_greeting_phrasefirst sentence on the phone: short, names the business, invites the caller to speak
project_representative_agent_voice_disclaimer_phraserecording or AI notice, if the owner wants or the law requires one
project_representative_agent_primary_language, ..._secondary_languages, ..._multilinguallanguages callers use
project_representative_agent_voice_speaking_styletone on the phone
project_representative_agent_providing_prices_explicit_constraintwhether and how the agent may name prices

project_representative_agent_voice_phone_number is the agent's own number and is managed by Newo: read it, never change it.

Knowledge (3-knowledge-base.md)

SettingWhat to check
project_attributes_products_and_servicesthe main catalog: services or menu, durations, prices if allowed
project_attributes_products_and_services_not_offeringwhat the business does not do
project_attributes_faqthe 10 to 20 questions callers ask most, with the owner's answers
project_attributes_current_specialscurrent offers, or empty
project_attributes_terms_and_conditionspolicies: cancellations, deposits, parking, age limits
project_attributes_rag_knowledge_base_append_textlong documents (price lists, policies) to add to the knowledge base; read its description first, it appends instead of replacing
project_attributes_rag_knowledge_base_append_websitesweb pages to import, with what to extract

Ask the owner for anything missing, or read their website and propose text for them to approve. Write in the language callers use.

Transfers to a person (4-agent-behavior.md)

SettingWhat to check
project_attributes_setting_transfer_call_enabled"True" only if the numbers below are set
project_business_working_hour_escalation_phonewho answers transfers during business hours
project_business_non_working_hour_escalation_phonewho answers outside business hours, or empty
project_attributes_setting_transfer_call_criteriawhen the agent should offer a person
project_business_manager_emailwhere the agent sends leads and escalations

Reports (5-reports.md)

SettingWhat to check
project_attributes_setting_session_ended_report_enabled"True" so the owner gets a summary after conversations
project_attributes_setting_session_ended_report_contentthe report types and fields; they must fit this business (a dental office needs no "catering order" report)
project_attributes_setting_session_ended_report_criteria_templatewho receives which report type, by email or SMS; every type named here must exist in the content setting
project_attributes_setting_session_ended_report_include_transcriptwhether the email includes the full transcript
project_attributes_setting_session_ended_full_processing_enabledreports need the full end-of-conversation processing; check that it is "True"

The report settings are filled from an industry template when the agent is created. If they mention things this business does not do, propose rewriting both content and criteria for its real cases, using the formats in 5-reports.md.

Booking, calendar, email and SMS to callers are covered in Connect external systems. Industry-specific settings (menus, appointment types, service areas) are listed in attributes/industries/; open the page for the business's industry.

3. Apply the changes

  1. Show the owner one list: setting, old value, new value. Get a "yes" (they may approve all at once or one by one).
  2. Change each attribute with a full-object PUT (API reference).
  3. Read each value back.
  4. If you changed working hours, time zone, languages or voice settings, publish the naf project (API reference) and wait 2 to 5 minutes.

4. Test

  1. Run a sandbox chat (API reference) with 3 to 5 questions that use the changed settings: "Are you open on Sunday?", "How much is ...?", "Can I talk to a person?". Creating the sandbox test user is itself a change: tell the owner and ask once. If the owner does not want it, skip to step 2.
  2. Ask the owner to call the agent's number, listen to the greeting and ask the same questions. Then read that call's transcript (Review conversations) and tell the owner what you saw.
  3. Report what worked and what did not. Fix and repeat.

When the owner is happy, offer the night launch (Launch at night).

Playbook: launch at night

Goal: for a few hours outside business hours, real callers reach the agent instead of voicemail. The owner sees how the agent handles real people with little risk, then reviews the calls the next morning.

Before the launch

Check with the owner and fix through settings (ask before each change):

  1. Configuration is finished (Finish the configuration) and the owner has made at least one test call.
  2. Hours and time zone are right. The agent decides "open" or "closed" from project_business_working_hours and project_business_time_zone. At night it should say the business is closed and offer what it can do (take a message, book, answer questions). If the hours say "open 24 hours", the agent treats the night as working time: ask whether that is true (a 24/7 service) or should become the real office hours.
  3. Transfers at night. Outside working hours the agent transfers to project_business_non_working_hour_escalation_phone; during working hours (including a 24/7 schedule) to project_business_working_hour_escalation_phone. Make sure the number used during the test window is answered, or set it to empty (or turn transfers off for the window) so the agent takes a message instead of transferring callers to a phone nobody picks up.
  4. Reports are on. project_attributes_setting_session_ended_report_enabled is "True" and the criteria send a report for every conversation to the owner, so no caller is lost.
  5. Bookings. If the agent can book, decide with the owner whether night bookings are real. project_attributes_setting_test_mode set to "True" stops real bookings and calendar events (the agent behaves as if they succeeded); leave it "False" for real bookings. Read its description in 4-agent-behavior-advanced.md before changing it.
  6. The agent's number. Read project_representative_agent_voice_phone_number; this is where calls must be forwarded.

Forwarding the business line

Forwarding is done by the owner on their phone service, not through the Newo API. Ask what the business uses (mobile carrier, landline provider, a cloud phone system such as RingCentral, Grasshopper or Google Voice, or a desk-phone PBX) and walk them through it:

After forwarding is on, ask the owner to call the business number from another phone and confirm the agent answers. Agree on the end time and remind the owner to turn forwarding off (unless they use a schedule).

During the night

Nothing is required. If the owner is awake and curious, you can check progress: GET /api/v1/bff/conversations/user-personas?page=1&per=20 shows new callers, and GET /api/v1/analytics/logs with levels=error for the last few hours shows errors.

The next morning

Go to Review conversations: review every call of the night, then Improve and fix.

Playbook: review conversations

Goal: the owner learns what callers wanted, how the agent did, and what to improve, in a short report. Transcripts contain callers' personal data: quote only what you need, and do not copy them anywhere except back to the owner.

1. Collect the conversations

  1. GET /api/v1/bff/conversations/user-personas?page=1&per=50 (newest first). Keep personas whose last_act_time falls in the period the owner asked about. Page on while the last item is still inside the period.
  2. Skip internal and test personas and recognize automated test calls as described in API reference (real callers are usually named User, so the name alone does not tell you who is real; sandbox actors are tests).
  3. For each persona, read each actor's history: GET /api/v1/chat/history?user_actor_id={actor_id}&page=1&per=100. integration_idn and connector_idn tell the channel: phone, web voice widget, website chat, text message.
  4. The history is newest first and mixes all conversations of that person. Order messages by datetime and split them into conversations where two messages are more than two minutes apart. is_agent: true is the agent; the text is payload.text.

2. Judge each conversation

For each conversation, write down:

When a conversation looks wrong and the reason is not clear, read the logs of that actor: GET /api/v1/analytics/logs?from_datetime=...&to_datetime=...&user_actor_ids={actor_id}&per=50 (48 hours at most) and look at what the agent looked up. Errors are not always tagged with the caller, so also read levels=error for the minutes of the call without the actor filter. Errors in the agent's own logic (not caused by a setting) are for Newo support: collect the time, the error message and the skill name, and give them to the owner to forward.

3. Report to the owner

Keep it short:

  1. Numbers: conversations, by channel, by outcome.
  2. Two or three good examples in one line each.
  3. Problems, most important first, each with one short quote and the cause you believe in (missing information, wrong setting, agent behavior).
  4. Proposed fixes, each as a concrete setting change. Ask which ones to apply, then follow Improve and fix.

Playbook: improve and fix

Goal: turn a problem the owner noticed, or one found in Review conversations, into a tested change. Most problems are fixed with settings. Code changes are rare and risky.

1. Find the cause

SymptomUsual causeWhere to fix
Wrong or invented fact (price, hours, service)the fact is missing or wrong in the settingsKnowledge settings: products and services, FAQ, terms, knowledge base text
"We are closed" when open, or the reverseworking hours or time zoneproject_business_working_hours, project_business_time_zone, then publish naf
Agent transfers too often or nevertransfer criteria or numbersproject_attributes_setting_transfer_call_criteria, escalation phones, project_attributes_setting_transfer_call_enabled
Wrong language or switches languagelanguage settingsprimary, secondary and multilingual agent settings
Greeting too long or uncleargreeting settingproject_representative_agent_voice_greeting_phrase
Talks too much, wrong tonespeaking styleproject_representative_agent_voice_speaking_style
Names prices it should not, or refuses toprice ruleproject_representative_agent_providing_prices_explicit_constraint
Owner got no reportreport settingsproject_attributes_setting_session_ended_report_enabled, criteria, project_business_manager_email
Booking failsbooking settings or the outside booking systemsee Connect external systems; read logs with levels=error
Error in the logs inside a skilla bug in the agent code or a setting the code readsread the skill and the setting it uses; prefer fixing the setting

To confirm a cause, read the logs of the conversation (GET /api/v1/analytics/logs with user_actor_ids and a window of 48 hours or less, see API reference) and the full description of the setting in the attribute reference.

2. Change, test, confirm

  1. Propose the change to the owner: setting, old value, new value, why. Wait for "yes".
  2. Apply it (API reference) and read it back.
  3. Publish naf if the setting is compiled at start (hours, time zone, languages, voice).
  4. Reproduce the original problem in a sandbox chat with a new test persona, or ask the owner to call. A fix is done only when the same question now gets the right answer.
  5. Tell the owner the result, with the old value at hand in case they want it back.

3. Changing skill code (last resort)

Change code only when no setting can fix the problem and the owner agrees after hearing the risks:

If the owner still wants it:

  1. Find the skill. V2: download the running version and follow project.yaml to the skill's file (API reference). Old designer: list agents, then the flow's skills (API reference, old designer (V1 archive)). Use logs (skill_idn, flow_idn of the failing step) to locate it.
  2. Save the complete current code before changing anything (V2: keep the downloaded ZIP).
  3. Learn the language: runner_type nsl or guidance (Jinja-like templates). Callable functions and their arguments: GET /api/v1/script/actions. Copy patterns from other skills in the same flow.
  4. Show the owner the change as a before and after of the changed lines. Wait for "yes".
  5. V2: create an editable copy of the running version, write the changed file, save the project attributes, publish the version and compare the attributes (API reference). If the publish fails or calls break, activate the previous version again. Old designer: PUT /api/v1/designer/flows/skills/{skill_id} with the full skill object, then publish the flow; on errors put the old code back and publish again.
  6. Wait two minutes and test.

Playbook: connect external systems

Goal: the agent books into the owner's calendar or booking system, sends conversation results to their CRM or other tools, and sends emails or text messages to callers when allowed. Each option below is a set of settings; read the full descriptions in the attribute reference before changing them, and ask the owner before each change.

First ask which tools the business uses: booking or scheduling system, calendar, CRM, a spreadsheet, Zapier or Make. project_attributes_info_crm may already say which CRM they use.

Reports to people (no integration needed)

The simplest way to get every conversation to the team: email and SMS reports after each conversation. See the Reports settings in Finish the configuration and 5-reports.md.

Send every conversation to another system (webhook)

After a conversation ends, the agent can POST a structured result to any URL: a CRM endpoint, a Zapier or Make webhook, or the owner's own server.

SettingPurpose
project_attributes_setting_session_ended_webhook_urlwhere to send
project_attributes_setting_session_ended_webhook_schemawhich fields to send
project_attributes_setting_session_ended_webhook_auth_headerauthorization header the receiver expects

Details and examples: 5-reports-advanced.md. A secret for the receiving system goes into the auth header setting; ask the owner to paste it, and do not repeat it in the conversation.

Test: make a short sandbox conversation or test call, then ask the owner to check that the record arrived.

Calendar appointments

project_attributes_setting_calendar_event_integration chooses how appointments become calendar events: disabled, calcom_integration (Cal.com) or google_integration (Google Calendar). Related settings: meeting duration, setup phrase, working-hours check (project_attributes_setting_meeting_...).

Connecting a Google account requires the owner to sign in to Google, which happens in the Newo portal, not through this API. If the google_calendar connector (GET /api/v1/integrations, then its connectors) is missing or not running, ask the owner to connect Google Calendar in the portal or to contact Newo support.

Booking systems

The booking settings (project_attributes_setting_booking_...) let the agent check availability and create bookings through an outside system's HTTP API: enabled switch, type, URLs, HTTP method, headers, request and validation schemas, confirmation phrases, email and SMS notifications. Industry pages describe ready-made options, for example restaurant reservation systems in industries/restaurant.md.

This is advanced: read every related description in 4-agent-behavior-advanced.md first, test with project_attributes_setting_test_mode set to "True" so no real booking is made, check the logs with levels=error, and switch test mode off only when the owner approves.

Email and SMS to callers during a conversation

SettingPurpose
project_attributes_setting_email_send_information_enabledallow emails to the caller
project_attributes_setting_email_send_information_allowed_content, ..._itemswhat an email may contain
project_attributes_setting_sms_send_information_enabledallow text messages to the caller
project_attributes_setting_sms_send_information_allowed_content, ..._itemswhat a text may contain
project_attributes_setting_session_ended_sms_enabled, ..._contentone promotional text after the conversation

Text messages to callers can be subject to consent and anti-spam rules in the business's country (for example, in the US, A2P 10DLC registration and opt-out handling). Make sure the owner knows before turning them on.

Incoming events and custom webhooks

GET /api/v1/webhooks and GET /api/v1/webhooks/incoming list the webhooks the account already has. Creating new webhook connections changes how the agent's code receives and sends events; do it only together with Newo support.

Look something up or act in another system during the conversation

Example: the caller asks for a table for two tomorrow at 3 pm. The agent checks free tables in the reservation system, tells the caller what is available, and books only after the caller says yes.

Conversation tools (settings, no code)

project_attributes_settings_platform_tools (JSON) adds tools the agent can use during a conversation. Each tool has:

Read the full description in the attribute reference (4-agent-behavior-advanced.md) before writing one. Rules:

MCP servers

The Newo platform can also connect to other systems' MCP servers (Integrations → MCP Integration Service → Add connector). A connector has a URL and one of three authorization types: headers, a bearer key (JWT), or OAuth2. With OAuth2, the owner signs in to the other system once to give access. The connector's idn is how the agent's code refers to it.

Today an MCP connector is used from skill code (a structured generation call that lists the connector), not from the conversation tools setting above. This is a code change: read Improve and fix first, and prefer the conversation tools with a webhook when the other system also has an HTTP API.

Keys and secrets for other systems go into the connector by the owner in the Newo portal, never through this chat.

Playbook: connect the business phone line

Goal: callers who dial the business's existing number reach the agent (always, after hours, or when nobody answers), and the agent can transfer calls back to people.

There are two ways. Ask the owner which phone system they use (a mobile or landline carrier, or a business phone system such as RingCentral, Nextiva, 8x8, Zoom Phone, Dialpad, Genesys, or their own PBX), then pick one:

WayWhenWho changes what
A. Call forwarding to the agent's numberalmost always; the simplestthe owner (or you, with their access) changes forwarding in their phone system; nothing changes in Newo
B. The agent registers as a SIP extension of the business phone systemthe business wants the agent inside its PBX (internal transfers, its own caller ID)both sides: an extension in the PBX, the SIP settings in Newo, and network access

Do not change both at once. Every step below needs the owner's "yes"; changes to a phone line affect real callers immediately.

1. Read the agent's phone setup

  1. The agent's number: the read-only attribute for the agent's phone number (see Finish the configuration), or GET /api/v1/integrations, the newo_voice integration, its connector newo_voice_connector, and the provider and number in its settings (API reference). Never show sip_password or keys.
  2. Transfers back to people: project_attributes_setting_transfer_call_enabled, ..._phone_numbers, ..._criteria, ..._destination_format (full_number, or short_code for internal extensions), and the escalation phone numbers for working and non-working hours. Read their descriptions in the attribute reference.

2. Way A: call forwarding

Decide with the owner when calls go to the agent:

Then set it up where the line lives:

Test:

  1. Ask the owner to call the business number from another phone and let it ring.
  2. Check that a new conversation appeared (API reference) and that the agent answered.
  3. When calls are forwarded, the agent may see the business number instead of the caller's number on some systems. Check the caller number in the new conversation; if every caller looks like the same person, tell the owner and Newo support.

3. Way B: the agent as a SIP extension

Newo connects to the business phone system by SIP registration (username and password of an extension), not by IP trunking.

On the business phone system (owner or their IT, or you with their admin access):

  1. Create an extension (SIP user) for the agent.
  2. Allow it to transfer calls to other extensions, and to call out in E.164 format if transfers to outside numbers are needed.
  3. Route calls to it (ring group, queue, after-hours rule).
  4. Collect: SIP server host and port, transport (UDP or TCP; say so if TLS is required), the extension's username, the caller ID, and whether the system only accepts known IP addresses.

On Newo:

  1. The newo_voice_connector provider becomes Custom SIP with these values. Do not ask the owner to paste the SIP password into the chat. Ask Newo support to enter it, or the owner to enter it in the Newo portal (Integrations).
  2. If the phone system accepts only known IP addresses, ask Newo support for Newo's addresses and to allow the business's server on Newo's side.
  3. Transfers: set ..._destination_format to short_code when transfers go to internal extensions.

Test: an inbound call through the PBX route, an outbound test if the agent calls out, and one transfer to a person. If the agent does not receive calls, the registration may have failed; Newo support can check it (the API does not show registration status today).

4. After it works

Playbook: get a phone number

Every agent gets a phone number when it is created, in a country close to the business. Use this playbook when the owner needs a number in another country or of another type (mobile, local, national, toll-free), or a second number.

1. What the owner needs

Ask:

2. What Newo can give

Typical documents for a business number in a regulated country (the exact list depends on the country and the number type):

Example, Germany: mobile numbers (+49 15x/16x/17x) and local numbers both need business documents; a local number also needs an address in its area code (Twilio's German requirements).

3. How to request it

  1. Collect the answers from step 1.
  2. Do not collect identity or company documents in the chat. Tell the owner that Newo support will send them a secure way to submit documents.
  3. Ask the owner to contact Newo support (or their Newo partner) with: account idn, country, number type, area code, calls/SMS, demo or production.
  4. When the number is assigned, test it: a call to the number reaches the agent (API reference).

Numbers cost money every month. Before asking for an extra number, make sure the owner agrees, and ask whether an unused number should be released.

Archive: API reference for the old Flow Designer (V1)

Archive. This is the reference as of 3 November 2026, before accounts moved to Flow Designer V2. Use it only when GET /api/v1/customer/settings/name/projects_v2_enabled is off or missing (see API reference). For every other account, use API reference.

Base URL https://app.newo.ai. All bodies are JSON. Send accept: application/json and, after the token step, Authorization: Bearer <access_token>.

Status of each request in this page:

Rules from the guide apply: ask the owner before every change, never DELETE.

Contents

  1. Authentication
  2. Account and projects
  3. Attributes (settings)
  4. Agents, flows and skills
  5. Publish
  6. Conversations and transcripts
  7. Logs
  8. Test chat (sandbox)
  9. Integrations and connectors
  10. Webhooks
  11. Knowledge base (AKB)
  12. Known limits

Authentication

POST /api/v1/auth/api-key/token (checked). Header x-api-key: <api_key>, no body.

TOKEN=$(curl -s -X POST https://app.newo.ai/api/v1/auth/api-key/token \
  -H "x-api-key: $NEWO_API_KEY" -H "accept: application/json" \
  | python3 -c 'import sys,json; print(json.load(sys.stdin)["access_token"])')
H=(-H "Authorization: Bearer $TOKEN" -H "accept: application/json")
curl -s "${H[@]}" https://app.newo.ai/api/v1/customer/profile

Response (HTTP 201): access_token, refresh_token, expires_in (the string "900": 15 minutes), token_type. When a request returns 401 or 403, request a new token with the API key and retry once; you do not need the refresh token.

Account and projects

RequestStatusReturns
GET /api/v1/customer/profilecheckedid, idn, organization_name, email, website, country, address, industry, ...; business fields are often empty
GET /api/v1/designer/projectscheckedlist of projects: id, idn, title, version, registry_idn, registry_item_idn, is_auto_update_enabled
GET /api/v1/designer/projects/by-id/{project_id}checkedone project
GET /api/v1/designer/registriescheckedproject registries (for version information only)

GET /api/v1/account returns 403 with an account API key; use the profile instead.

The receptionist is the project with idn naf. Keep its id: most requests below need it. is_auto_update_enabled: true means Newo updates the project to new releases automatically, and an update replaces changed skill code (see Improve and fix).

Attributes

Read

RequestStatusNotes
GET /api/v1/bff/customer/attributes?include_hidden=truechecked{"groups": [...], "attributes": [...]}, 300 to 500 items, more than 1 MB
GET /api/v1/bff/projects/{project_id}/attributes?query=&include_hidden=truecheckedproject attributes of one project, same shape

Each attribute: id, idn, value, title, description, group, is_hidden, is_read_only, possible_values, value_type (string, enum, json, number, bool, ...).

Values are always strings. Booleans are the strings "True" and "False". JSON attributes hold a JSON document serialized as a string. An empty setting is "" or " ". value_type is a hint, not a guarantee (a phone number of type number can hold "+1...").

is_read_only: true marks settings managed by Newo (industry, the agent's phone number): do not change them. Some values are secrets (keys, auth headers, tokens): do not display them, see the rules in the guide.

The response is large. Fetch it once, save it to a local file, and filter by idn instead of printing everything:

curl -s "${H[@]}" "https://app.newo.ai/api/v1/bff/customer/attributes?include_hidden=true" \
  > attrs.json
python3 -c '
import json, sys
attrs = {a["idn"]: a for a in json.load(open("attrs.json"))["attributes"]}
for idn in sys.argv[1:]:
    a = attrs.get(idn); print(idn, "=>", repr(a["value"]) if a else "(missing)")
' project_business_name project_business_working_hours project_business_time_zone

Change

PUT /api/v1/customer/attributes/{attribute_id} (from client code) for a customer attribute, PUT /api/v1/designer/projects/{project_id}/attributes/{attribute_id} (from client code) for a project attribute.

Always send the whole attribute, not only the value. Read the current object, replace value, send back these fields: idn, value, title, description, group, is_hidden, possible_values, value_type. A body with only {"value": ...} erases the title, description and allowed values.

python3 - <<'PY'
import json, os, urllib.request
token, idn, new_value = os.environ["TOKEN"], "project_business_working_hours", "..."
base = "https://app.newo.ai"
hdr = {"Authorization": f"Bearer {token}", "accept": "application/json",
       "content-type": "application/json"}
req = urllib.request.Request(f"{base}/api/v1/bff/customer/attributes?include_hidden=true",
                             headers=hdr)
attrs = {a["idn"]: a for a in json.load(urllib.request.urlopen(req))["attributes"]}
a = attrs[idn]
print("old value:", a["value"])
body = {k: a[k] for k in ("idn", "title", "description", "group", "is_hidden",
                          "possible_values", "value_type")}
body["value"] = new_value
req = urllib.request.Request(f"{base}/api/v1/customer/attributes/{a['id']}", method="PUT",
                             data=json.dumps(body).encode(), headers=hdr)
print(urllib.request.urlopen(req).status)
PY

For an enum attribute the new value must be one of possible_values. For a json attribute, validate the JSON before sending. Read the value back after the change.

Agents, flows and skills

RequestStatusReturns
GET /api/v1/bff/agents/list?project_id={project_id}checkedagents with their flows (id, idn, title, publication dates) and persona
GET /api/v1/designer/flows/{flow_id}/skillscheckedskills with full code: id, idn, title, prompt_script, runner_type (nsl or guidance), model, parameters
GET /api/v1/designer/flows/{flow_id}/eventscheckedevents that start skills in the flow
GET /api/v1/designer/flows/{flow_id}/statesfrom client codeflow state variables
GET /api/v1/designer/projects/{project_id}/librariescheckedshared libraries with their skills
GET /api/v1/script/actionscheckedthe functions (actions) skill code can call, with arguments

GET /api/v1/designer/skills/{skill_id} returns 404; read skills through their flow.

The naf project has agents such as ConvoAgent (the conversation logic, about 30 flows), GeneralManagerAgent (setup, reports, knowledge), TaskManager, EmailWorker, SmsWorker, MultiLocationAgent, TestAgent.

Change a skill (last resort)

PUT /api/v1/designer/flows/skills/{skill_id} (from client code). Send the complete skill object you read from the flow, with prompt_script replaced. Then publish the flow. Library skills: PATCH /api/v1/designer/libraries/{library_id}/skills/{skill_id} with {"prompt_script": "..."} (from client code).

Read Improve and fix before changing code.

Publish

RequestStatusBody
POST /api/v1/designer/flows/{flow_id}/publishfrom client code{"version": "1.0", "description": "<what changed>", "type": "public"}
POST /api/v1/designer/projects/{project_id}/publishfrom client codesame body

A flow publish makes changed skills live. A project publish of naf publishes the project and starts the agent's initialization again, which recompiles settings such as working hours, time zone, languages and scenarios. Allow 2 to 5 minutes before testing. Errors come back in message and reasons; show them to the owner in plain words.

Conversations

RequestStatusReturns
GET /api/v1/bff/conversations/user-personas?page=1&per=50checkedpeople who talked to the agent, most recent first: id, name, last_session_id, session_is_active, last_act_time, last_act_text, act_count, actors, not_found
GET /api/v1/bff/conversations/user-personas/{persona_id}checkedone person
GET /api/v1/chat/history?user_actor_id={actor_id}&page=1&per=100checkedmessages of one actor, newest first: id, type, datetime, is_agent, external_event_id, payload.text, payload.arguments

Each actor in actors has id, integration_idn, connector_idn, external_id and contact_information. Channels:

How to read the list:

GET /api/v1/bff/conversations/acts returns 403 with an account API key; use the chat history.

Logs

GET /api/v1/analytics/logs (checked). Query parameters:

ParameterMeaning
from_datetime, to_datetimerequired in practice; UTC YYYY-MM-DDTHH:MM:SS. Keep the window at 48 hours or less: an unfiltered 72-hour request returned HTTP 500 (a filtered one may work); on a 500, split the period
perpage size
cursorvalue of metadata.next_cursor from the previous page
levelsinfo, warning, error (comma-separated)
log_typessystem, operation, call (comma-separated)
project_idn, flow_idn, skill_idnfilter by where the log came from
user_actor_ids, user_persona_ids, agent_persona_idsfilter by conversation participant
external_event_id, runtime_context_idfollow one event or one skill run
messagetext filter

Each item: log_id, level, log_type, project_idn, message, datetime, data. For call logs, data holds name (the function called), parameters, result, context (with flow_idn, user_actor_id), source (with skill_idn), execution_time_ms, runtime_context_id and sometimes prompt_script. Items are large: use small pages (per=20). metadata.total can be null; page with cursor until next_cursor is null.

Typical uses: levels=error over the night of a test launch; user_actor_ids=<actor> to see what the agent did during one call. Errors are not always tagged with the caller (context.user_actor_id can be null), so to find the errors of one call, also query levels=error for the minutes of that call without the actor filter.

Sandbox

A text conversation with the agent for testing, without a phone call (from client code, flow used by the Newo CLI):

  1. GET /api/v1/integrations (checked), find the integration with idn sandbox.
  2. GET /api/v1/integrations/{integration_id}/connectors (checked), take a connector whose status is running. Most agents have test_agent_sandbox or convo_agent_sandbox.
  3. POST /api/v1/customer/personas with {"name": "setup-test-<random>", "title": "setup-test-<random>"} returns the new persona id.
  4. POST /api/v1/customer/personas/{persona_id}/actors with {"name": "<same name>", "external_id": "<6 random hex characters>", "integration_idn": "sandbox", "connector_idn": "<connector_idn from step 2>", "time_zone_identifier": "<business time zone>"} returns the actor id.
  5. POST /api/v1/chat/user/{actor_id} with {"text": "Hi, are you open on Sunday?", "arguments": []}.
  6. Poll GET /api/v1/chat/history?user_actor_id={actor_id}&page=1&per=100 every second, up to 60 seconds, until a message with is_agent: true newer than your message appears. Continue the conversation by repeating steps 5 and 6 with the same actor.

The sandbox tests what the agent says. It does not test the phone line, voice, transfers or SMS delivery; for those, ask the owner to make a real test call.

Integrations and connectors

RequestStatusReturns
GET /api/v1/integrationscheckedintegrations: id, idn, title, description, is_disabled, connector_settings_descriptions (which settings a connector takes)
GET /api/v1/integrations/{integration_id}/connectorscheckedconnectors: id, connector_idn, title, status (running, ...), settings ([{"idn", "value"}])
GET /api/v1/integrations/{integration_id}/settingsfrom client codeintegration-level settings
PUT /api/v1/integrations/connectors/{connector_id}from client codechange title, status or settings
POST /api/v1/integrations/{integration_id}/connectorsfrom client code{"title", "connector_idn", "integration_idn", "settings": [{"idn", "value"}]}

Connector objects can contain an api_key field, and settings such as sip_password. Never show them to the owner or anyone else. Change connector settings only when a playbook says so; the phone (newo_voice) connectors are managed by Newo.

Webhooks

RequestStatusReturns
GET /api/v1/webhookscheckedoutgoing webhooks: id, idn, description, connector_idn, url, command_idns
GET /api/v1/webhooks/incomingcheckedincoming webhooks: id, idn, url, connector_idn, event_idns, allowed_ips
POST /api/v1/webhooksfrom client code{"connector_idn", "event_idn", "url", "method", "headers", "body_template"}
POST /api/v1/webhooks/incomingfrom client code{"connector_idn", "event_idn"}, returns the URL to give to the outside system

AKB

The knowledge base belongs to the persona of the GeneralManagerAgent agent in naf (take persona.id from the agents list).

RequestStatusReturns
GET /api/v1/akb/topics?persona_id={persona_id}&page=1&per=100&order_by=created_atcheckeditems[].topic: topic_name, topic_summary, topic_facts, labels, source, confidence
POST /api/v1/akb/append-manualfrom client codeadds one article: {"persona_id", "topic_name", "topic_summary", "topic_facts": [...], "confidence": 100, "source": "<who added it>", "labels": [...]}

Each item is {"topic": {...}, "fuzzy_search_fields_score": ...}. In responses, labels is a string holding a list ("['rag_context', ...]") and topic_facts is a JSON string; parse them before use. When adding an article, send both as real JSON arrays. The topics endpoint has no working text search; page through and filter locally. Copy the labels of existing topics (they include rag_context).

If project_attributes_setting_knowledge_source is akb_studio, the agent does not use this knowledge base; knowledge is managed in Newo Knowledge Studio. For ordinary owners, adding knowledge through the attribute project_attributes_rag_knowledge_base_append_text is simpler (see Finish the configuration).

Known limits