npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@oriacall/sdk

v0.12.3

Published

TypeScript SDK for the Oriacall Developer API.

Readme

@oriacall/sdk

TypeScript SDK for the Oriacall Developer API.

Install

npm install @oriacall/sdk

Requirements:

  • Node.js 18 or newer.
  • An Oriacall Developer API client ID and secret.
  • Server-side usage only. Do not expose clientSecret in browser code.

Create API Credentials

In Oriacall, open:

Settings -> Developer API -> Manage API Clients

Create a client, select the scopes it can request, and copy the client_secret immediately. Oriacall shows each client secret only once.

Available scopes:

hello:read
objectives:read
objectives:write
objective_custom_fields:manage
agents:read
calls:read
calls:write
leads:read
leads:write
lead_custom_fields:manage
webhooks:read
webhooks:write

The token request can only request scopes that were granted to that API client.

Quickstart

import { createOriacallClient } from "@oriacall/sdk";

const oriacall = createOriacallClient({
  clientId: process.env.ORIACALL_CLIENT_ID!,
  clientSecret: process.env.ORIACALL_CLIENT_SECRET!,
  scope: ["hello:read", "objectives:read", "agents:read", "calls:read", "leads:read"],
});

const hello = await oriacall.hello.get();
console.log(hello.data.message, hello.requestId);

const calls = await oriacall.calls.list({ limit: 50 });
console.log(calls.data.data, calls.requestId);

The SDK requests and caches a short-lived access token using client credentials, then sends it as a bearer token for API calls.

Client Reference

createOriacallClient(options)

Creates an Oriacall API client.

const oriacall = createOriacallClient({
  baseUrl: "https://api.oriacall.com",
  clientId: process.env.ORIACALL_CLIENT_ID!,
  clientSecret: process.env.ORIACALL_CLIENT_SECRET!,
  scope: ["calls:read"],
  retries: 2,
  retryBaseDelayMs: 250,
  retryMaxDelayMs: 2000,
  onResponse: ({ method, path, status, requestId }) => {
    console.log({ method, path, status, requestId });
  },
});

Options:

| Option | Type | Required | Description | | --- | --- | --- | --- | | clientId | string | Yes | Developer API client ID. | | clientSecret | string | Yes | Developer API client secret. Keep this server-side. | | baseUrl | string | No | API base URL. Defaults to https://api.oriacall.com. | | scope | string \| string[] | No | Space-separated string or array of requested token scopes. If omitted, the token request uses all scopes granted to the client. | | fetch | typeof fetch | No | Custom fetch implementation. Defaults to global fetch. | | onResponse | (event: OriacallResponseEvent) => void | No | Called for every SDK-managed HTTP response, including token requests. | | retries | number | No | Retry count for token requests and GET endpoints. Defaults to 0. | | retryBaseDelayMs | number | No | Initial retry delay. Defaults to 250. | | retryMaxDelayMs | number | No | Maximum retry delay. Defaults to 2000. |

Returns a namespaced client:

oriacall.getAccessToken();
oriacall.hello.get();
oriacall.objectives.list();
oriacall.objectives.update("objective-id", { customFields: { region: "north" } });
oriacall.objectives.paginate();
oriacall.objectiveCustomFields.list();
oriacall.objectiveCustomFields.create({ key: "region", label: "Region", type: "select", options: ["north", "south"] });
oriacall.objectiveCustomFields.update("region", { label: "Sales Region" });
oriacall.agents.list();
oriacall.agents.paginate();
oriacall.calls.list();
oriacall.calls.get("call-id");
oriacall.calls.update("call-id", { recordedAt: "2026-06-10T14:30:00Z" });
oriacall.calls.upload({ idempotencyKey: "crm-call-123", agent: { externalId: "agent-1", name: "Morgan" }, lead: { externalId: "lead-1", firstName: "Ada", lastName: "Lovelace" }, audio: { file: audioBlob, filename: "call.mp3" } });
oriacall.calls.queueAnalysis("call-id");
oriacall.calls.waitForAnalysis("call-id");
oriacall.calls.paginate();
oriacall.leads.list();
oriacall.leads.get("lead-id");
oriacall.leads.update("lead-id", { customFields: { crm_stage: "qualified" } });
oriacall.leads.upsertByExternalId("crm-lead-id", { firstName: "Ada", lastName: "Lovelace" });
oriacall.leads.paginate();
oriacall.leadCustomFields.list();
oriacall.leadCustomFields.create({ key: "crm_stage", label: "CRM Stage", type: "select", options: ["new", "qualified"] });
oriacall.leadCustomFields.update("crm_stage", { label: "CRM Stage" });
oriacall.webhooks.endpoints.list();
oriacall.webhooks.endpoints.create({ url: "https://example.com/oriacall/webhooks", events: ["analysis.completed", "analysis.failed"] });
oriacall.webhooks.endpoints.update("endpoint-id", { isActive: false });
oriacall.webhooks.endpoints.rotateSecret("endpoint-id");
oriacall.webhooks.endpoints.test("endpoint-id");
oriacall.webhooks.endpoints.delete("endpoint-id");
oriacall.raw.GET("/v1/hello", { headers: { Authorization: `Bearer ${await oriacall.getAccessToken()}` } });

Response Envelope

All SDK endpoint methods return a response envelope:

type OriacallApiResponse<T> = {
  data: T;
  status: number;
  requestId?: string;
};

Use requestId in logs and support requests. It maps to the API X-Request-Id response header.

Pagination

List endpoints use cursor pagination.

const firstPage = await oriacall.calls.list({ limit: 50 });

if (firstPage.data.pagination.nextCursor) {
  const secondPage = await oriacall.calls.list({
    limit: 50,
    cursor: firstPage.data.pagination.nextCursor,
  });
}

List option fields shared by paginated endpoints:

| Option | Type | Description | | --- | --- | --- | | limit | number | Number of items to return. Defaults to 50; maximum is 100. | | cursor | string | Cursor from the previous response's pagination.nextCursor. |

The SDK also includes async iterable helpers:

for await (const call of oriacall.calls.paginate({ limit: 50 })) {
  console.log(call.id);
}

Pagination helpers are available for objectives, agents, calls, leads, and webhooks.endpoints.

Methods

oriacall.getAccessToken()

Requests or returns a cached bearer token.

const token = await oriacall.getAccessToken();

Returns: Promise<string>.

oriacall.hello.get()

Checks credentials and connectivity.

Required scope: hello:read.

const response = await oriacall.hello.get();
console.log(response.data.message);

Returns: Promise<OriacallApiResponse<HelloResponse>>.

oriacall.objectives.list(options?)

Lists organization objectives.

Objective records include customFields, an object keyed by organization-defined objective custom field keys.

Required scope: objectives:read.

Options: ListObjectivesOptions

const response = await oriacall.objectives.list({ limit: 50 });

for (const objective of response.data.data) {
  console.log(objective.id, objective.name);
}

Returns: Promise<OriacallApiResponse<ObjectivesListResponse>>.

Options include limit, cursor, and objectiveCustomFields filters. objectiveCustomFields maps to the API's objectiveCustom[...] query parameters.

await oriacall.objectives.list({
  objectiveCustomFields: {
    region: "north",
    priority: { gte: 5 },
  },
});

oriacall.objectives.update(objectiveId, input)

Updates custom field values for an objective. Send null to clear a field.

Required scope: objectives:write.

Input: ObjectiveUpdateRequest

const response = await oriacall.objectives.update("objective-id", {
  customFields: {
    region: "north",
    priority: 10,
  },
});

console.log(response.data.data.customFields);

Returns: Promise<OriacallApiResponse<ObjectiveResponse>>.

oriacall.objectives.paginate(options?)

Iterates organization objectives across all pages.

Required scope: objectives:read.

Options: ListObjectivesOptions

for await (const objective of oriacall.objectives.paginate({ limit: 100 })) {
  console.log(objective.id, objective.name);
}

Returns: AsyncGenerator<Objective>.

oriacall.agents.list(options?)

Lists organization agents.

Agent records include nullable externalId when you store an ID from another system.

Required scope: agents:read.

Options: ListAgentsOptions

| Option | Type | Description | | --- | --- | --- | | limit | number | Number of agents to return. Defaults to 50; maximum is 100. | | cursor | string | Cursor from the previous response. | | objectiveId | string | Optional objective ID filter. |

const response = await oriacall.agents.list({ limit: 50, objectiveId: "objective-id" });

for (const agent of response.data.data) {
  console.log(agent.id, agent.externalId, agent.name);
}

Returns: Promise<OriacallApiResponse<AgentsListResponse>>.

oriacall.agents.paginate(options?)

Iterates organization agents across all pages.

Required scope: agents:read.

Options: ListAgentsOptions

for await (const agent of oriacall.agents.paginate({ objectiveId: "objective-id" })) {
  console.log(agent.id, agent.externalId, agent.name);
}

Returns: AsyncGenerator<Agent>.

oriacall.calls.list(options?)

Lists organization calls. List responses do not include transcripts.

Required scope: calls:read.

Options: ListCallsOptions

| Option | Type | Description | | --- | --- | --- | | limit | number | Number of calls to return. Defaults to 50; maximum is 100. | | cursor | string | Cursor from the previous response. | | objectiveId | string | Optional objective ID filter. | | leadId | string | Optional lead ID filter. | | agentId | string | Optional agent ID filter. | | createdAfter | string | Optional ISO 8601 lower bound for call creation time. | | createdBefore | string | Optional ISO 8601 upper bound for call creation time. | | recordedAfter | string | Optional ISO 8601 lower bound for source recording time. Falls back to createdAt when recordedAt is null. | | recordedBefore | string | Optional ISO 8601 upper bound for source recording time. Falls back to createdAt when recordedAt is null. | | sortBy | "createdAt" \| "recordedAt" | Optional sort field. Defaults to createdAt; recordedAt falls back to createdAt when null. | | leadCustomFields | Record<string, CustomFieldFilterValue> | Optional filters on lead custom fields attached to calls. |

const response = await oriacall.calls.list({
  limit: 50,
  objectiveId: "objective-id",
  recordedAfter: "2026-01-01T00:00:00.000Z",
  sortBy: "recordedAt",
  leadCustomFields: {
    crm_stage: "qualified",
  },
});

for (const call of response.data.data) {
  console.log(call.id, call.status, call.recordedAt, call.createdAt);
}

createdAfter and createdBefore filter by Oriacall upload/record creation time. Use recordedAfter, recordedBefore, and sortBy: "recordedAt" for original call chronology.

Returns: Promise<OriacallApiResponse<CallsListResponse>>.

oriacall.calls.get(callId)

Gets a call detail record, including transcript data when available.

Required scope: calls:read.

Transcript turn speaker values can be agent, client, or system. system represents telephony infrastructure such as voicemail greetings, carrier messages, transfer prompts, or tones; it is not a human participant.

const response = await oriacall.calls.get("call-id");
console.log(response.data.data.transcript);
console.log(response.data.data.callResult);
console.log(response.data.data.analysis?.callObservations);

Returns: Promise<OriacallApiResponse<CallDetailResponse>>.

oriacall.calls.update(callId, input)

Updates original source recording time for a call.

Required scope: calls:write.

Input: CallUpdateRequest

const response = await oriacall.calls.update("call-id", {
  recordedAt: "2026-06-10T14:30:00Z",
});
console.log(response.data.data.recordedAt, response.requestId);

Returns: Promise<OriacallApiResponse<CallResponse>>.

oriacall.calls.upload(input)

Uploads an audio recording, upserts the agent and lead by externalId, creates the call, and optionally queues analysis.

Required scope: calls:write.

The API requires an idempotency key for uploads. Reusing the same idempotencyKey with the same request returns the original response; reusing it with different metadata or audio returns an idempotency_key_conflict error.

objectiveId is optional. When provided, Oriacall associates the call with that organization objective. When omitted, Oriacall associates the call with an existing objective in the organization.

The maximum audio upload size is configured by an Oriacall superadmin and defaults to 20 MB. Your server/proxy upload limits must also allow that size.

Options: UploadCallInput

| Option | Type | Description | | --- | --- | --- | | idempotencyKey | string | Required unique key for safe retries. | | objectiveId | string \| null | Optional organization objective ID. | | externalId | string \| null | Optional call ID from your system. | | recordedAt | string \| null | Optional ISO 8601 datetime when the call was recorded in your source system. Returned as recordedAt; createdAt remains the Oriacall upload time. | | queueAnalysis | boolean | Optional. Defaults to true; set false to upload now and queue later. | | agent.externalId | string | Required agent ID from your system. | | agent.name | string | Required when creating a new agent. | | agent.email | string \| null | Optional agent email. | | agent.phone | string \| null | Optional agent phone. | | lead.externalId | string | Required lead/prospect ID from your system. | | lead.firstName | string | Required when creating a new lead. | | lead.lastName | string | Required when creating a new lead. | | lead.email | string \| null | Optional lead email. | | lead.phone | string \| null | Optional lead phone. | | lead.customFields | Record<string, unknown> | Optional organization-defined lead custom fields. | | audio.file | Blob \| ArrayBuffer \| Uint8Array | Required audio file data. In Node, a Buffer from readFile() can be passed directly. | | audio.filename | string | Optional filename sent in multipart upload. | | audio.contentType | string | Optional MIME type, for example audio/mpeg. |

import { readFile } from "node:fs/promises";

const buffer = await readFile("./call.mp3");

const response = await oriacall.calls.upload({
  idempotencyKey: "crm-call-789",
  externalId: "crm-call-789",
  recordedAt: "2026-06-10T14:30:00Z",
  objectiveId: "objective-id", // optional organization objective
  queueAnalysis: true,
  agent: {
    externalId: "agent-123",
    name: "Morgan Agent",
  },
  lead: {
    externalId: "prospect-456",
    firstName: "Ada",
    lastName: "Lovelace",
    email: "[email protected]",
    customFields: {
      crm_stage: "qualified",
    },
  },
  audio: {
    file: buffer,
    filename: "call.mp3",
    contentType: "audio/mpeg",
  },
});

console.log(response.data.data.id, response.data.data.analysisStatus, response.requestId);

Call summaries include callResult, callResultLabel, and callQualityScore. analysisStatus is one of pending, queued, processing, completed, or failed. queueStatus is queued, processing, completed, failed, or null when analysis has not been queued. analysisStage is audio_pass, text_pass, publishing, completed, or null when analysis has not been queued. Internal dead-letter and cancelled runs are exposed as failed. Completed call analysis includes summary, callStrengths, callWeaknesses, callObservations, objections, and alerts.

Returns: Promise<OriacallApiResponse<CallResponse>>.

oriacall.calls.queueAnalysis(callId)

Queues analysis for a call that was uploaded with queueAnalysis: false.

Required scope: calls:write.

const response = await oriacall.calls.queueAnalysis("call-id");
console.log(response.data.data.analysisStatus, response.data.data.queueStatus);

Returns: Promise<OriacallApiResponse<CallResponse>>.

oriacall.calls.waitForAnalysis(callId, options?)

Polls oriacall.calls.get(callId) until the call analysis status is completed or failed.

Required scope: calls:read.

Options: WaitForAnalysisOptions

| Option | Type | Description | | --- | --- | --- | | intervalMs | number | Poll interval. Defaults to 2000. | | timeoutMs | number | Timeout before throwing analysis_timeout. Defaults to 120000. |

const response = await oriacall.calls.waitForAnalysis("call-id", { timeoutMs: 180000 });
console.log(response.data.data.analysis);

Returns: Promise<OriacallApiResponse<CallDetailResponse>>.

oriacall.calls.paginate(options?)

Iterates organization calls across all pages.

Required scope: calls:read.

Options: ListCallsOptions

for await (const call of oriacall.calls.paginate({ leadId: "lead-id" })) {
  console.log(call.id);
}

Returns: AsyncGenerator<CallSummary>.

oriacall.leads.list(options?)

Lists organization leads. The leads:read scope includes lead email and phone contact details.

Lead records include nullable externalId when you store an ID from another system, and a customFields object for organization-defined CRM fields.

Required scope: leads:read.

Options: ListLeadsOptions

| Option | Type | Description | | --- | --- | --- | | limit | number | Number of leads to return. Defaults to 50; maximum is 100. | | cursor | string | Cursor from the previous response. | | objectiveId | string | Optional objective ID filter. | | createdAfter | string | Optional ISO 8601 lower bound for lead creation time. | | createdBefore | string | Optional ISO 8601 upper bound for lead creation time. | | customFields | Record<string, CustomFieldFilterValue> | Optional filters on lead custom fields. |

const response = await oriacall.leads.list({
  limit: 50,
  objectiveId: "objective-id",
  customFields: {
    crm_stage: "qualified",
    deal_value: { gte: 10000 },
  },
});

for (const lead of response.data.data) {
  console.log(lead.id, lead.externalId, lead.email, lead.phone, lead.customFields);
}

Returns: Promise<OriacallApiResponse<LeadsListResponse>>.

oriacall.leads.get(leadId)

Gets a lead detail record, including email and phone contact details.

Required scope: leads:read.

const response = await oriacall.leads.get("lead-id");
console.log(response.data.data.externalId, response.data.data.email, response.data.data.phone, response.data.data.customFields);

Returns: Promise<OriacallApiResponse<LeadDetailResponse>>.

oriacall.leads.update(leadId, input)

Updates a lead and/or its custom fields.

Required scope: leads:write.

Input: LeadUpdateRequest

const response = await oriacall.leads.update("lead-id", {
  email: "[email protected]",
  customFields: {
    crm_stage: "qualified",
    renewal_date: "2026-09-01",
  },
});

console.log(response.data.data.customFields);

Returns: Promise<OriacallApiResponse<LeadDetailResponse>>.

oriacall.leads.upsertByExternalId(externalId, input)

Creates or updates a lead by the integrating CRM/system ID. This is the preferred write method for CRM integrations because callers can use their own stable lead ID.

Required scope: leads:write.

Input: LeadUpsertRequest

const response = await oriacall.leads.upsertByExternalId("hubspot_123", {
  firstName: "Ada",
  lastName: "Lovelace",
  email: "[email protected]",
  customFields: {
    crm_stage: "qualified",
    deal_value: 12000,
  },
});

console.log(response.data.data.id, response.data.data.customFields);

Returns: Promise<OriacallApiResponse<LeadDetailResponse>>.

oriacall.leads.paginate(options?)

Iterates organization leads across all pages.

Required scope: leads:read.

Options: ListLeadsOptions

for await (const lead of oriacall.leads.paginate({ createdAfter: "2026-01-01T00:00:00.000Z" })) {
  console.log(lead.id, lead.externalId);
}

Returns: AsyncGenerator<Lead>.

oriacall.leadCustomFields.list(options?)

Lists organization lead custom field definitions.

Required scope: leads:read.

Options: ListLeadCustomFieldsOptions

| Option | Type | Description | | --- | --- | --- | | includeArchived | boolean | Include archived definitions. Defaults to false. |

const response = await oriacall.leadCustomFields.list();
console.log(response.data.data);

Returns: Promise<OriacallApiResponse<LeadCustomFieldsListResponse>>.

oriacall.leadCustomFields.create(input)

Creates a lead custom field definition. Supported types are text, number, boolean, date, datetime, select, and multi_select.

Required scope: lead_custom_fields:manage.

Input: LeadCustomFieldCreateRequest

const response = await oriacall.leadCustomFields.create({
  key: "crm_stage",
  label: "CRM Stage",
  type: "select",
  options: ["new", "qualified", "customer"],
  isFilterable: true,
});

console.log(response.data.data.key);

Returns: Promise<OriacallApiResponse<LeadCustomFieldResponse>>.

oriacall.leadCustomFields.update(key, input)

Updates mutable metadata for a lead custom field definition. Field keys and types are immutable.

Required scope: lead_custom_fields:manage.

Input: LeadCustomFieldUpdateRequest

await oriacall.leadCustomFields.update("crm_stage", {
  label: "CRM Pipeline Stage",
  archived: false,
});

Returns: Promise<OriacallApiResponse<LeadCustomFieldResponse>>.

oriacall.objectiveCustomFields.list(options?)

Lists organization objective custom field definitions.

Required scope: objectives:read.

Options: ListObjectiveCustomFieldsOptions

| Option | Type | Description | | --- | --- | --- | | includeArchived | boolean | Include archived definitions. Defaults to false. |

const response = await oriacall.objectiveCustomFields.list();
console.log(response.data.data);

Returns: Promise<OriacallApiResponse<ObjectiveCustomFieldsListResponse>>.

oriacall.objectiveCustomFields.create(input)

Creates an objective custom field definition. Supported types are text, number, boolean, date, datetime, select, and multi_select.

Required scope: objective_custom_fields:manage.

Input: ObjectiveCustomFieldCreateRequest

const response = await oriacall.objectiveCustomFields.create({
  key: "region",
  label: "Region",
  type: "select",
  options: ["north", "south"],
  isFilterable: true,
});

console.log(response.data.data.key);

Returns: Promise<OriacallApiResponse<ObjectiveCustomFieldResponse>>.

oriacall.objectiveCustomFields.update(key, input)

Updates mutable metadata for an objective custom field definition. Field keys and types are immutable.

Required scope: objective_custom_fields:manage.

Input: ObjectiveCustomFieldUpdateRequest

await oriacall.objectiveCustomFields.update("region", {
  label: "Sales Region",
  archived: false,
});

Returns: Promise<OriacallApiResponse<ObjectiveCustomFieldResponse>>.

oriacall.webhooks.endpoints.list(options?)

Lists webhook endpoints for the authenticated API client.

Required scope: webhooks:read.

Options: ListWebhookEndpointsOptions

const response = await oriacall.webhooks.endpoints.list({ limit: 50 });
console.log(response.data.data);

Returns: Promise<OriacallApiResponse<WebhookEndpointsListResponse>>.

oriacall.webhooks.endpoints.create(input)

Creates a webhook endpoint. The signing secret is returned only once in this response.

Required scope: webhooks:write.

Input: WebhookEndpointCreateRequest

const response = await oriacall.webhooks.endpoints.create({
  url: "https://example.com/oriacall/webhooks",
  events: ["analysis.completed", "analysis.failed"],
});

console.log(response.data.data.id, response.data.data.secret);

Returns: Promise<OriacallApiResponse<WebhookEndpointSecretResponse>>.

oriacall.webhooks.endpoints.update(endpointId, input)

Updates a webhook endpoint URL, event subscriptions, or active state.

Required scope: webhooks:write.

Input: WebhookEndpointUpdateRequest

const response = await oriacall.webhooks.endpoints.update("endpoint-id", {
  events: ["analysis.completed"],
  isActive: true,
});

Returns: Promise<OriacallApiResponse<WebhookEndpointResponse>>.

oriacall.webhooks.endpoints.delete(endpointId)

Deletes a webhook endpoint.

Required scope: webhooks:write.

await oriacall.webhooks.endpoints.delete("endpoint-id");

Returns: Promise<OriacallApiResponse<null>>.

oriacall.webhooks.endpoints.rotateSecret(endpointId)

Rotates the endpoint signing secret. The new secret is returned only once.

Required scope: webhooks:write.

const response = await oriacall.webhooks.endpoints.rotateSecret("endpoint-id");
console.log(response.data.data.secret);

Returns: Promise<OriacallApiResponse<WebhookEndpointSecretResponse>>.

oriacall.webhooks.endpoints.test(endpointId)

Queues a webhook.test delivery to validate endpoint reachability and signature verification.

Required scope: webhooks:write.

const response = await oriacall.webhooks.endpoints.test("endpoint-id");
console.log(response.data.data.eventType, response.data.data.status);

Returns: Promise<OriacallApiResponse<WebhookTestResponse>>.

oriacall.webhooks.endpoints.paginate(options?)

Iterates webhook endpoints across all pages.

Required scope: webhooks:read.

for await (const endpoint of oriacall.webhooks.endpoints.paginate({ limit: 50 })) {
  console.log(endpoint.id, endpoint.events);
}

Returns: AsyncGenerator<WebhookEndpoint>.

verifyOriacallWebhookSignature(input)

Verifies a webhook HMAC signature. Pass the raw request body string exactly as received.

import { verifyOriacallWebhookSignature } from "@oriacall/sdk";

const valid = await verifyOriacallWebhookSignature({
  body: rawBody,
  secret: process.env.ORIACALL_WEBHOOK_SECRET!,
  signature: request.headers.get("Oriacall-Signature") ?? "",
  timestamp: request.headers.get("Oriacall-Timestamp") ?? "",
});

Returns: Promise<boolean>.

Lower-Level Calls

For advanced integrations, raw exposes a typed lower-level OpenAPI client. You must attach authorization yourself.

const { data, error } = await oriacall.raw.GET("/v1/hello", {
  headers: {
    Authorization: `Bearer ${await oriacall.getAccessToken()}`,
  },
});

Errors

API errors throw OriacallApiError.

import { OriacallApiError, createOriacallClient } from "@oriacall/sdk";

try {
  await oriacall.calls.list({ limit: 50 });
} catch (error) {
  if (error instanceof OriacallApiError) {
    console.error(error.status, error.code, error.message, error.requestId);
  }

  throw error;
}

Error fields:

| Field | Type | Description | | --- | --- | --- | | status | number | HTTP status code. | | code | string | Stable API error code. | | message | string | Human-readable message. | | requestId | string \| undefined | Request ID from X-Request-Id or error body. | | details | Record<string, unknown> \| undefined | Structured error details when present. | | retryAfter | number \| undefined | Seconds to wait before retrying when present. | | isRateLimited | boolean | true for rate limit errors. | | response | OriacallErrorResponse \| undefined | Full API error response when available. |

Common API error codes:

missing_token
invalid_token
invalid_client
invalid_scope
insufficient_scope
rate_limited
invalid_request
internal_error
call_not_found
call_external_id_conflict
analysis_already_queued
analysis_timeout
ai_config_missing
evaluation_grid_missing
audio_not_found
idempotency_key_conflict
idempotency_key_in_progress
lead_not_found
custom_field_not_found
custom_field_conflict

Retries

Configure retry/backoff for safe SDK-managed requests. The SDK retries token requests and GET endpoints for 429, 500, 502, 503, and 504, and respects Retry-After when present.

const oriacall = createOriacallClient({
  clientId: process.env.ORIACALL_CLIENT_ID!,
  clientSecret: process.env.ORIACALL_CLIENT_SECRET!,
  scope: ["calls:read"],
  retries: 2,
  retryBaseDelayMs: 250,
  retryMaxDelayMs: 2000,
});

Token Behavior

The SDK:

  • Requests tokens using client credentials.
  • Caches the access token in memory.
  • Refreshes the token before expiry.
  • Never stores credentials or tokens on disk.

Base URL

The SDK defaults to:

https://api.oriacall.com

If Oriacall support gives you a custom API base URL, pass it explicitly:

const oriacall = createOriacallClient({
  baseUrl: "https://api.oriacall.com",
  clientId: process.env.ORIACALL_CLIENT_ID!,
  clientSecret: process.env.ORIACALL_CLIENT_SECRET!,
  scope: ["calls:read"],
});

Exported Types

The package exports these TypeScript types:

import type {
  Agent,
  AgentsListResponse,
  CallDetailResponse,
  CallResponse,
  CallsListResponse,
  CallSummary,
  CallUpdateRequest,
  CallUploadMetadata,
  CustomFieldFilters,
  CustomFieldFilterValue,
  HelloResponse,
  Lead,
  LeadCustomField,
  LeadCustomFieldCreateRequest,
  LeadCustomFieldResponse,
  LeadCustomFieldUpdateRequest,
  LeadCustomFieldsListResponse,
  LeadDetailResponse,
  LeadUpdateRequest,
  LeadUpsertRequest,
  LeadsListResponse,
  ListAgentsOptions,
  ListCallsOptions,
  ListLeadCustomFieldsOptions,
  ListLeadsOptions,
  ListObjectiveCustomFieldsOptions,
  ListObjectivesOptions,
  ListWebhookEndpointsOptions,
  Objective,
  ObjectiveCustomField,
  ObjectiveCustomFieldCreateRequest,
  ObjectiveCustomFieldResponse,
  ObjectiveCustomFieldUpdateRequest,
  ObjectiveCustomFieldsListResponse,
  ObjectiveResponse,
  ObjectiveUpdateRequest,
  ObjectivesListResponse,
  UploadCallInput,
  VerifyWebhookSignatureInput,
  OriacallApiResponse,
  OriacallClientOptions,
  OriacallErrorResponse,
  OriacallResponseEvent,
  OriacallResponseMetadata,
  WaitForAnalysisOptions,
  WebhookEndpoint,
  WebhookEndpointCreateRequest,
  WebhookEndpointResponse,
  WebhookEndpointSecretResponse,
  WebhookEndpointUpdateRequest,
  WebhookEndpointsListResponse,
  WebhookEventPayload,
  WebhookTestResponse,
} from "@oriacall/sdk";

Generated OpenAPI-derived types are included in the package declaration files, so editors can inspect the exact response fields for each method.