Quincer AI Docs Home Support Start free

Connect

Custom REST tools

Give your AI assistant a brand-new skill by pointing it at any HTTP endpoint — your database, your CRM, a SaaS API, an internal service. No code. A guided wizard walks you through it one step at a time, or you can let Describe it with AI draft the setup for a well-known service. This is the same mechanism that powers our own dashboard assistant’s abilities.

i

Custom REST tools require the Scale plan plus the Custom Tools add-on. Find them under Integrations → Custom REST, then Add custom tool. Without the add-on the button is disabled and a banner links you to Billing.

How a tool works

A custom tool is one HTTP request the assistant can make on its own. When the conversation calls for it, the model collects the inputs you defined, the platform fills them into the request, calls your endpoint, and hands the response back to the model to use in its reply.

  1. You define a tool: a name, a description (so the model knows when to use it), the HTTP request, and the inputs to collect.
  2. A visitor says something that needs it (“where’s my order?”).
  3. The model gathers the inputs, the platform makes the call, and the model answers with the live result.

The Add wizard

Clicking Add custom tool opens a guided, no-code wizard. It starts with a choice screen — Describe it with AI (best for well-known systems like Jira, Stripe, or HubSpot) or Set it up manually (best for your own or in-house APIs). Either way you land in the same five-step builder; the AI path just pre-fills it first.

Connect a system
×
How do you want to set this up?

Point the assistant at any HTTP endpoint — no code.

Describe it with AI Fastest for popular apps
Best for well-known systems like Jira, Stripe, or HubSpot. Say what you want; we draft every field.
Set it up manually
Best for your own or in-house systems. A guided 5-step wizard — no JSON.
{ }
Advanced — set it up with raw JSON
Full control: request body, timeout, verified-visitor.

The choice screen — Describe it with AI, the no-code wizard, or the Advanced raw-JSON form.

The manual builder has five steps you can jump between at any time:

  1. Name — a short handle the model calls (e.g. track_shipment; lowercase letters, digits, and underscores, starting with a letter, up to 64 chars) and a plain-English description of what the tool does. The model reads the description to decide when to use the tool, so be specific about the inputs and outputs.
  2. Fields — the information the tool needs, built visually (see The field builder below). No JSON, no brackets.
  3. Address — the HTTP method (GET, POST, PUT, PATCH, or DELETE) and the full https:// URL. Tap a field to drop it into the URL — no typing brackets (see Placeholders). If the URL references a {{input.x}} that has no matching field, the step blocks you with a warning until you add the field.
  4. Sign in — how the tool authenticates (see Sign in below). Secrets are stored encrypted.
  5. Test — send one real request so you know it works before it goes live (see Test it).
Connect a system
Step 3 of 5
×
Name Fields 3Address 4Sign in 5Test
Where do we send the request?

The web address of the system. Tap a field to drop it in — no typing brackets.

GET
https://api.example.com/orders/{{input.order_id}}
Tap to insert: + order_id + account_id

{{input.field}} and {{identity.field}} are filled in at runtime. https is required.

Start over
BackContinue

The Address step — tap a field chip to insert {{input.…}} instead of typing brackets.

Under the hood the visual builder assembles the exact same request shape the raw form produces, so nothing about how tools run changes — the wizard just hides the JSON.

The field builder

Step 2 is a visual list — one row per piece of information the tool collects. Click Add a field for each. Every row has:

What should the assistant collect?
×
tracking_number Text ▾ Required ×
include_history Yes / no ▾ Required ×
+ Add a field

Types: Text · Number · Yes / no · Date · List of text

The Fields step — a visual builder instead of raw JSON Schema.

Row controlWhat it is
Field nameThe name the model fills in, e.g. tracking_id. This is what you reference as {{input.tracking_id}} in the Address (or body).
TypeOne of Text, Number, Yes / no, Date, or List of text. Quincer turns these into the right underlying type (text → string, number → number, yes/no → boolean, date → a date-formatted string, list of text → an array of strings).
RequiredA toggle. On means the model must collect a value before the tool can run.
DescriptionA short line under the row — “describe it so Quincer knows what to put here.” The model uses this to fill the field correctly.

Sign in

Step 4 is a segmented picker for how your endpoint authenticates. Pick one style and fill in its inputs; Quincer stores the secret encrypted and adds the right header to every request:

How does the system sign requests in?
×
No sign-inAPI keyBearerUser & passwordCustom
Token
••••••••••••saved — Replace

Sends Authorization: Bearer <token>. Secrets are stored encrypted and never shown again.

The Sign in step — pick an auth style; no hand-written headers.

StyleWhat it does
No sign-inThe system is public — no header is added.
API keyYou pick the header name (default Authorization) and paste the key value. Quincer sends that header verbatim on every request.
BearerPaste a token; Quincer sends Authorization: Bearer <token>.
User & passwordEnter a username and password; Quincer base64-encodes user:password and sends Authorization: Basic … (HTTP Basic).
CustomAdd one or more raw header rows (name + value) — for APIs that want a non-standard header, or several headers at once.

Send who the visitor is

A phone caller is not signed in, so there is no verified token and no {{identity.…}} to inject — but you usually still know something useful about them: the number they called from. Switch Send who the visitor is on for a tool and every call to it carries that identity as HTTP headers, so your endpoint can look the person up and answer with their own data.

The toggle is on the tool’s card in Integrations → Custom REST tools, and also inside the tool’s own edit screen next to Require verified visitor. It is off by default — sending your customers’ phone numbers and email addresses to a third-party endpoint is a decision you make, not one we make for you. It is per tool, so a tool that looks up an order can receive the caller’s number while a tool that fetches your public price list never sees it.

HeaderExample
Quincer-Visitor-Identity-Typephone, email, or the social network’s id type
Quincer-Visitor-Identity+14155550123 — phone numbers are always sent in full E.164 form
Quincer-Visitor-Identity-Verifiedtrue / false — see the warning below
Quincer-Visitor-Identity-Sourcewhere it came from, e.g. voice_caller_id or web_identity
Quincer-Channelvoice, web, and so on

These are the same headers an MCP server receives, for the same reason: one behaviour, so a tool behaves the same way whichever kind it is. They are sent as headers and never as tool arguments, so the model cannot invent, alter, or omit them.

On an outbound call nothing is sent. The far end there is someone Quincer dialled, not a caller identifying themselves — reporting the number we just rang as “the caller” would tell your endpoint something it already knows, and would be an outright wrong-identity lookup if a switchboard or another person picked up.

!

Caller ID is not proof of identity. On a phone call the number comes from the carrier and can be spoofed, so it is sent with Quincer-Visitor-Identity-Verified: false. Treat it as a lookup hint — fine for “find this account”, not enough on its own to release private details or authorise a change. A signed-in web visitor is sent as true. If your endpoint ignores that header, it is trusting whoever is on the line.

i

This is not the same as “Require verified visitor”. That setting gates the tool — it refuses to run at all without a signed-in visitor, and injects verified claims into the request. This one only tells your endpoint who is asking, verified or not, and never blocks a call. Use both together when a tool acts on someone’s data: the gate for authorisation, the headers for the lookup.

Describe it with AI

The fastest way to build a tool for a well-known service. On the choice screen pick Describe it with AI, describe what you want in plain English, and click Draft the setup. Try a prompt like:

Create a Jira issue in our SUPPORT project
Look up a shipment by tracking number in our orders API

The assistant drafts the method, endpoint, fields, and sign-in for you using its knowledge of well-known APIs, then drops you into the wizard pre-filled so you review and finish — usually just pasting your real API token where it left a placeholder (it never invents secrets). Nothing goes live until you save.

It also knows Quincer’s own API, so prompts like “create a tool that builds a new Quincer persona” or “let the assistant list my leads” produce the real endpoint and the correct Bearer cw_dev_ developer-key auth automatically.

i

If your draft needs something the no-code steps can’t hold — a request body (most POST tools, like “create a Jira issue”), a custom timeout, or a verified-visitor rule — Quincer hands the full draft to the Advanced (raw JSON) form pre-filled, and tells you which part it couldn’t show, instead of dropping it. (A response path is no longer one of those — the wizard’s Test step now has a “which part of the response?” field, so read tools like “get a list of X” stay in the guided flow.)

Advanced (raw JSON)

Some tools go beyond what the guided steps cover — anything that needs a request body, sets a custom timeout or rate limit, or restricts the tool to a verified visitor. For those, the choice screen has a third option below the two cards: Advanced — set it up with raw JSON. It opens the full field-by-field editor. You also land here automatically when an AI draft carries one of those (see above), pre-filled, with a note explaining which part the guided builder couldn’t show. (Extracting a field from the response — the response path — is handled right in the wizard’s Test step now, so it no longer sends you here.)

Advanced · raw JSONcreate_jira_issue
×
Body template — POST / PUT / PATCH
{ "fields": { "project": { "key": "SUPPORT" }, "summary": "{{input.summary}}" } }
Response JSONPath
data.key
Blank or $ = whole body
Timeout (ms)
10000
1000–30000
Require verified visitor
Only run for a signed-in visitor; inject {{identity.*}} claims.
CancelSave changes

The Advanced form adds a request body, response path, timeout, and verified-visitor — for tools the wizard can’t express.

The Advanced form adds these fields on top of the basics:

FieldWhat it is
Input schema (JSONSchema)The raw JSON Schema for the inputs — the same thing the field builder assembles, edited directly. Each property gets a description; list the truly required ones in required.
Headers (JSON)A JSON object of headers (auth, content type). Paste your real secrets here.
Body template (optional)Shown for POST/PUT/PATCH (not GET/DELETE): the request body as JSON, with {{input.field}} and {{identity.…}} placeholders. Substitution is deep (works inside nested JSON).
Response JSONPath (optional)A dotted path into the JSON response (e.g. data.shipment.status) to return just that part to the model. Leave it blank — or use $ — to return the whole response body.
Timeout (ms)How long to wait for the endpoint before giving up. Between 1000 and 30000 ms; the default is 10000.
Require verified visitor (optional)Only let the tool run for a signed-in visitor. Reveals two more fields: Required claims (comma-separated — calls are rejected if any is missing from the verified token) and Claims to inject (an input field → claim map so the model can’t spoof identity — values are overwritten from the verified token). See Visitor sign-in.

Editing a tool

Click the pencil on any tool in the Custom REST list. Editing isn’t re-walking the wizard — you land on a review-and-edit accordion of collapsed cards and open just the part you want to change: Basics (name, method, description), Information it needs (the field builder), Address (method + URL + variable chips), and Sign in (the auth picker). A saved secret shows as •••• saved with a Replace button so you never have to re-enter it to tweak something else. An inline Test connection button runs a real request, and Save changes stays disabled until a section actually differs.

Edit toollookup_shipment
×
Basics
GET · Look up a shipment by tracking number
Information it needs
tracking_number (required)
Address
GET https://api.example.com/shipments/…
Sign in
Bearer token
Edited
1 section edited
CancelSave changes

Editing opens a review screen — jump to any section; the Edited pill marks what changed.

Tools that use fields the visual builder can’t hold — a request body, a response path, a custom timeout, verified-visitor requirements, HTTP Basic auth, or a schema/headers shape the builder doesn’t model — open in the Advanced (raw JSON) form instead, so a rich tool is never silently corrupted by editing it visually.

Placeholders

Use these in the Address (URL) and, in the Advanced form, the body template — substitution is deep (works inside nested JSON):

The visual chip only inserts {{input.<field>}} and {{identity.account_id}}; the other {{identity.…}} tokens are still valid at runtime — type them into the URL, or use the Advanced form.

Example 1 — create an AI persona

Teach the assistant to spin up new personas on command, using Quincer’s own REST API. This one POSTs a body, so build it with Describe it with AI (“create a tool that builds a new Quincer persona”) or the Advanced form — the no-code steps don’t carry a body. First create a key under Integrations → API keys with the personas:write scope, then:

Namecreate_persona
MethodPOST
DescriptionCreate a new AI persona for this brand. Use when the operator asks to add or create a persona. Inputs: name and prompt.
Endpointhttps://chat.quincer.com/api/v1/personas

Input schema

{
  "type": "object",
  "properties": {
    "name":   { "type": "string", "description": "The new persona's name" },
    "prompt": { "type": "string", "description": "The persona's system prompt" }
  },
  "required": ["name", "prompt"]
}

Headers — the Quincer API uses a Bearer token (your key starts with cw_dev_):

{ "Authorization": "Bearer cw_dev_YOUR_KEY", "Content-Type": "application/json" }

Body template

{ "name": "{{input.name}}", "systemPrompt": "{{input.prompt}}" }

Now say “create a persona called Spanish Support that always replies in Spanish” and it appears under Personas.

Example 2 — look up a shipment in Postgres

Expose a read-only query over a Postgres table via a REST layer like PostgREST or Supabase. This one is a GET with no body, so you can build it end to end in the no-code wizard: one Text field tracking_number, the URL below (tap the field’s chip to drop it in), and Custom sign-in with the two Supabase headers.

Namelookup_shipment
MethodGET
DescriptionLook up a shipment by its tracking number. Returns the current status, carrier, and ETA. Use when a visitor asks where their order is.
Endpointhttps://YOUR-PROJECT.supabase.co/rest/v1/shipments?tracking_number=eq.{{input.tracking_number}}&select=status,carrier,eta

Field

Sign in — Custom, two header rows:

apikey:        YOUR_SUPABASE_ANON_KEY
Authorization: Bearer YOUR_SUPABASE_ANON_KEY

Tip: a REST layer returns an array of rows. To hand the model just the first match, set Response JSONPath to 0 in the Advanced form (a response path isn’t part of the no-code steps). Keep the role/key read-only and scoped with row-level security so the tool can only see what you intend.

Example 3 — open a Jira support ticket

Let the assistant file a Jira issue when it can’t resolve something. This is the ideal Describe it with AI case: say “create a Jira issue in our SUPPORT project” and the draft — including Jira’s nested Atlassian Document Format body — lands in the Advanced form for you to finish (the body means it can’t stay in the no-code steps). Auth is HTTP Basic with your Atlassian email + an API token, base64-encoded as email:token.

Namecreate_jira_issue
MethodPOST
DescriptionOpen a Jira issue in the SUPPORT project. Use when the visitor reports a problem you can't resolve. Inputs: summary and description.
Endpointhttps://YOUR-DOMAIN.atlassian.net/rest/api/3/issue

Input schema

{
  "type": "object",
  "properties": {
    "summary":     { "type": "string", "description": "Short issue title" },
    "description": { "type": "string", "description": "What the visitor reported" }
  },
  "required": ["summary", "description"]
}

Headers

{
  "Authorization": "Basic YOUR_BASE64_EMAIL_AND_TOKEN",
  "Content-Type": "application/json"
}

Body template

{
  "fields": {
    "project":   { "key": "SUPPORT" },
    "issuetype": { "name": "Task" },
    "summary":   "{{input.summary}}",
    "description": {
      "type": "doc", "version": 1,
      "content": [{ "type": "paragraph", "content": [
        { "type": "text", "text": "{{input.description}}" }
      ]}]
    }
  }
}

(Jira’s description uses Atlassian Document Format, hence the nested shape. Describe it with AI writes this for you if you’d rather not hand-roll it.)

Test it

The wizard’s final step — and an inline Test connection button on the edit accordion — sends one real request from Quincer to your endpoint, using a sample value for each field, and shows you the status, the latency, and the response body. Do this before it goes live.

  1. On the Test step (or the edit screen), click Send a test request / Test connection. A green card confirms the connection and shows the returned body; a red one explains what failed.
  2. Save the tool. It appears in the Custom REST list — toggle Enabled if it isn’t already.
  3. Open your widget (or the preview) and ask something that should trigger it; watch the model collect the inputs, call your endpoint, and answer with the live result.

The test runs as you (the operator), not a signed-in chat visitor, so {{identity.…}} tokens can’t be filled in there — they’ll resolve in a real chat once a visitor is signed in. If the tool doesn’t fire in chat, tighten the Description so it’s unmistakable when the tool applies, and double-check required fields.

Security & limits