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_version and tools, 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=oauth2 chooses the auth object inside the call templates. ?products= takes a comma separated list of scope groups.
  • ETag and If-None-Match are supported (304). The UTCP-Version and API-Version headers 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 as Authorization: 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/token for the scope it needs (for example revenue_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.