UTCP
The Universal Tool Calling Protocol lets an AI agent read a manual of tools and then call the API directly, with its own credentials. Origin publishes a UTCP 1.0.1 manual of the whole REST API v1 (51 tools, manual version 1.20261101.0). There is no proxy in between: every tool is an http call template to /api/v1, so rate limits, idempotency, scopes, IP allow-lists and request logs work exactly as for any other API client.
Prefer MCP? The MCP server at /api/mcp (OAuth 2.1) stays available. The UTCP manual, the OpenAPI 3.1 document and the SDKs are generated from the same definitions, so they never disagree.
Discovery
GET /utcp(also/.well-known/utcp.json) returns the manual:utcp_version,manual_versionandtools, nothing else, so strict parsers accept it.- Without credentials you get every tool (cacheable for 5 minutes). With
Authorization: Bearer <API key or access token>you get only the tools that key may call (a read scope hides create, update and delete). ?auth=api_key(default) or?auth=oauth2chooses the auth object inside the call templates.?products=takes a comma separated list of scope groups.ETagandIf-None-Matchare supported (304). TheUTCP-VersionandAPI-Versionheaders tell you what you got.
# public manual (every tool, cacheable)
curl https://app.originpixel.in/utcp
# only the tools this key may call
curl -H "Authorization: Bearer $ORIGIN_API_KEY" https://app.originpixel.in/utcp
# OAuth 2.0 client-credentials call templates, two products only
curl "https://app.originpixel.in/utcp?auth=oauth2&products=revenue_engine,front_desk"Credentials and variables
The manual contains placeholders, never secrets. UTCP clients fill them from their own variables, namespaced by the name you register the manual under (manual origin + ORIGIN_API_KEY = origin_ORIGIN_API_KEY; underscores in the manual name are doubled).
- API key:
${ORIGIN_API_KEY}, sent asAuthorization: Bearer opk_live_.... Create keys under Developers > API keys. - OAuth 2.0 client credentials:
${ORIGIN_CLIENT_ID}and${ORIGIN_CLIENT_SECRET}of a confidential OAuth app; each tool asks/api/oauth/tokenfor the scope it needs (for examplerevenue_engine:write).
Examples with the official SDKs
TypeScript: npm i @utcp/sdk @utcp/http. Python: pip install utcp utcp-http. Full files are in integrations/utcp/examples of the platform repository.
import { UtcpClient } from "@utcp/sdk";
import "@utcp/http";
const client = await UtcpClient.create(process.cwd(), {
variables: { origin_ORIGIN_API_KEY: process.env.ORIGIN_API_KEY! },
manual_call_templates: [{
name: "origin",
call_template_type: "http",
http_method: "GET",
url: "https://app.originpixel.in/utcp",
auth: { auth_type: "api_key", api_key: "Bearer ${ORIGIN_API_KEY}", var_name: "Authorization", location: "header" },
}],
});
const lead = await client.callTool("origin.create_lead", {
body: { name: "Website enquiry", source: "website" },
"Idempotency-Key": crypto.randomUUID(),
});How a tool maps to the API
The request body is the body input (body_field), Idempotency-Key becomes a header (header_fields), {id} in the URL is filled from the id input, and every other input becomes a query parameter (filters such as stage[in], limit, cursor). Errors are RFC 9457 problem details, as everywhere in the API.
{
"name": "create_lead",
"description": "AI Revenue Engine (leads, campaigns): create a lead. ...",
"inputs": {
"type": "object",
"properties": {
"body": { "type": "object", "properties": { "name": { "type": "string" }, "source": { "type": "string" } } },
"Idempotency-Key": { "type": "string", "maxLength": 255 }
},
"required": ["body"]
},
"outputs": { "type": "object", "properties": { "object": { "const": "lead" }, "id": { "type": "string" } } },
"tags": ["origin", "revenue_engine", "leads", "write"],
"tool_call_template": {
"call_template_type": "http",
"http_method": "POST",
"url": "https://app.originpixel.in/api/v1/leads",
"content_type": "application/json",
"body_field": "body",
"header_fields": ["Idempotency-Key"],
"auth": { "auth_type": "api_key", "api_key": "Bearer ${ORIGIN_API_KEY}", "var_name": "Authorization", "location": "header" }
}
}Tools
- Contacts
- list_contacts, get_contact, create_contact, update_contact, delete_contact
- AI Front Desk (conversations, messages, bookings, knowledge)
- list_conversations, get_conversation, list_messages, get_message, list_bookings, get_booking, create_booking, update_booking, list_knowledge_articles, get_knowledge_article, create_knowledge_article, update_knowledge_article, delete_knowledge_article, list_conversation_messages
- AI Revenue Engine (leads, campaigns)
- list_leads, get_lead, create_lead, update_lead, list_campaigns, get_campaign
- AI Voice Workforce (calls, call campaigns)
- list_calls, get_call, list_voice_campaigns, get_voice_campaign
- AI Customer Experience (tickets, reviews)
- list_tickets, get_ticket, create_ticket, update_ticket, list_reviews, get_review, create_review
- AI Sales Workforce (prospects)
- list_prospects, get_prospect, create_prospect, update_prospect
- AI Business Intelligence (metrics)
- list_metrics, get_metric
- AI Back-Office Workforce (documents, records)
- list_documents, get_document, list_records, get_record
- AI Content Studio (posts)
- list_posts, get_post, create_post, update_post
- Authentication
- get_me
Using other UTCP tools inside Origin
Businesses can add external UTCP manuals under Developers > External tools (UTCP). Their tools become actions in AI Automations, Copilot and voice agents. For safety, only http, sse and streamable_http tools run (never command-line or MCP templates from a manual), tools may only call https addresses on the manual's own host or hosts the admin allowed, credentials are stored encrypted, tools that change data need a person's approval for every call unless the admin decides otherwise, and every call is logged.