Preview Foundation

Server API

Server API is the backend-only integration surface for enterprise systems. It uses tenant-scoped secret keys for server-to-server calls, token exchange, contact sync, report export, and signed webhook delivery.

Server API Keys

Create keys in Dashboard > Developer > Server API. The secret is shown once after create or rotate. Ringnity stores only a hash, so copy it into your backend secret manager immediately.

Need a beginner token endpoint guide?

Public widget key

Safe for browser install snippets. It identifies the tenant website experience and is protected by allowed-domain checks.

Server API key

Secret credential for the client backend only. Never put it in frontend code, mobile apps, public repos, or browser-accessible config.

Backend flow

browser client
  -> server owned by client
  -> Ringnity backend

The browser asks your backend for a short-lived Visitor, Agent, or Admin SDK token. Your backend calls Ringnity with the Server API key.

Environment variables

RINGNITY_API_BASE_URL=https://api.ringnity.com
RINGNITY_SERVER_API_KEY=rn_sk_live_xxx

Auth model

The Server API uses a tenant-scoped secret key. The key must be stored only on the client backend. Requests can use either the Authorization header or X-Ringnity-Server-Key.

Authorization: Bearer SERVER_API_KEY
X-Ringnity-Server-Key: SERVER_API_KEY

Security rules

  • Credentials map to one tenant by client_id.
  • Keys are hashed at rest and the raw secret is shown once.
  • Rotate replaces the old secret immediately.
  • Revoked keys stop authenticating but remain visible for audit.

Scopes

Give each backend only the permissions it needs. These are the standard Server API scopes exposed in the dashboard.

server:agent-token:write

Create short-lived Agent SDK tokens.

server:admin-token:write

Create short-lived Admin SDK tokens.

server:visitor-context:write

Create trusted Visitor SDK context tokens.

server:reports:read

Read and export report summaries, timeseries, and productivity data.

server:contacts:read

List and read tenant contacts.

server:contacts:write

Create, update, or delete tenant contacts.

server:webhook:read

Read webhook configuration and delivery logs.

server:webhook:write

Create, update, test, or disable webhook destinations.

Use the Server API object model

Backend helper example

Install the backend helper in your customer backend. The Server API key stays on the server, then the helper creates short-lived tokens for Visitor, Agent, and Admin SDKs.

import { RingnityServerApi } from '@ringnity/server-api';

const ringnity = RingnityServerApi.create({
  baseUrl: process.env.RINGNITY_API_BASE_URL,
  apiKey: process.env.RINGNITY_SERVER_API_KEY!
});

const health = await ringnity.system.health();
const account = await ringnity.account.get();
const readiness = await ringnity.account.sdkReadiness();
const reportExport = await ringnity.reports.export({
  period: '30days',
  format: 'csv'
});

const visitorContext = await ringnity.tokens.visitorContext({
  visitor: {
    externalId: 'crm-1001',
    name: 'Budi Santoso',
    phone: '+62 812-3456-789'
  },
  metadata: {
    tier: 'priority'
  },
  expiresIn: 900
});

const agentToken = await ringnity.tokens.agent({
  username: 'agent.one',
  scopes: [
    'agent:profile:read',
    'agent:presence:read',
    'agent:presence:write',
    'agent:conversations:read',
    'agent:conversations:write',
    'agent:messages:read',
    'agent:messages:write',
    'agent:media:delete',
    'agent:calls:read',
    'agent:calls:write'
  ],
  expiresIn: 900
});

const adminToken = await ringnity.tokens.admin({
  username: 'admin.one',
  expiresIn: 900
});

await ringnity.contacts.delete('contact_id');
ringnity.system.health()

Check whether the Server API credential can reach Ringnity.

ringnity.account.get()

Read tenant profile for the credential owner.

ringnity.account.sdkReadiness()

Read Visitor SDK readiness and service availability.

ringnity.tokens.visitorContext(input)

Create a trusted short-lived context token for Visitor SDK.

ringnity.tokens.agent(input)

Create a short-lived Agent SDK token for CRM workspaces.

ringnity.tokens.admin(input)

Create a short-lived Admin SDK token for internal portals.

ringnity.contacts.list(options)

List tenant contacts with pagination and search.

ringnity.contacts.upsert(input)

Create or idempotently update a CRM contact.

ringnity.contacts.delete(id)

Delete a stale or duplicated tenant contact.

ringnity.reports.export(options)

Download report data as JSON or CSV for BI and back-office workflows.

ringnity.webhooks.create(input)

Create a signed webhook destination.

ringnity.webhooks.test(event)

Send a signed test event and record the delivery.

Exact API reference

The Server API helper is the recommended application surface. Use Scalar when you need exact endpoints, request bodies, responses, examples, auth schemes, or error codes generated from OpenAPI.

Open Scalar API reference

Visitor context token

When to use it

Use public visitor fields for harmless identity such as display name. Use contextToken when your backend needs to attach trusted CRM context without exposing a Server API key in browser code.

curl -X POST "https://api.ringnity.com/api/server/visitor-context-token" \
  -H "Authorization: Bearer SERVER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "visitor": {
      "externalId": "crm-1001",
      "name": "Budi Santoso",
      "phone": "+62 812-3456-789",
      "email": "budi@example.com"
    },
    "metadata": {
      "tier": "priority",
      "accountType": "credit-card"
    },
    "expiresIn": 900
  }'

Use the token in the website

Your website asks your own backend for a context token, then passes that short-lived token to Visitor SDK. The Server API key stays on your backend.

const response = await fetch('/api/ringnity/context-token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ customerId: 'crm-1001' })
});

const { contextToken } = await response.json();

Ringnity.init({
  slug: 'your-tenant-slug',
  contextToken
});

Common context token errors

400 SERVER_VISITOR_CONTEXT_EMPTY
401 SERVER_API_KEY_INVALID
403 SERVER_API_SCOPE_DENIED
413 SERVER_VISITOR_CONTEXT_TOO_LARGE
401 SDK_CONTEXT_TOKEN_INVALID

Agent SDK token

When to use it

Use this when your CRM or internal workspace needs to show Ringnity agent profile, presence, inbox, conversation messages, or Ringnity call controls. Your backend creates the token; your frontend uses only the short-lived Agent SDK token.

curl -X POST "https://api.ringnity.com/api/server/sdk-token/agent" \
  -H "Authorization: Bearer SERVER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "agent.one",
    "scopes": [
      "agent:profile:read",
      "agent:presence:read",
      "agent:presence:write",
      "agent:conversations:read",
      "agent:conversations:write",
      "agent:messages:read",
      "agent:messages:write",
      "agent:media:delete",
      "agent:calls:read",
      "agent:calls:write"
    ],
    "expiresIn": 900
  }'

Use the token from an internal page

const response = await fetch('/api/ringnity/agent-token', {
  method: 'POST'
});

const { token } = await response.json();

const agent = await RingnityAgent.create({ token });

const inbox = await agent.conversations.list({
  status: 'open',
  limit: 10
});

Required scope

Add server:agent-token:write to the Server API key.

401 SERVER_API_KEY_MISSING
401 SERVER_API_KEY_INVALID
403 SERVER_API_SCOPE_DENIED
404 SERVER_AGENT_NOT_FOUND

Admin SDK token

Create a read-only admin token

Use this for internal tenant admin portals that need readiness, domains, service status, subscription summary, AI readiness, and staff summary. The actor must be an active tenant admin.

curl -X POST "https://api.ringnity.com/api/server/sdk-token/admin" \
  -H "Authorization: Bearer SERVER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "admin.one",
    "scopes": [
      "admin:tenant:read",
      "admin:readiness:read",
      "admin:domains:read",
      "admin:services:read",
      "admin:subscription:read",
      "admin:ai-readiness:read",
      "admin:staff-summary:read",
      "admin:reports:export",
      "admin:ai-knowledge:write"
    ],
    "expiresIn": 900
  }'

Webhooks preview examples

This section shows the shortest flow. For event status, signature verification, retry policy, and delivery log details, open Webhooks.

Create a webhook destination

Store your receiver URL and shared secret on Ringnity. The secret is used to sign every delivery and is not returned by list endpoints.

curl -X POST "https://api.ringnity.com/api/server/webhooks" \
  -H "Authorization: Bearer SERVER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "CRM webhook",
    "url": "https://sadavir.id/ringnity/webhook",
    "secret": "shared-secret-from-your-receiver",
    "events": ["conversation.message.received"]
  }'

Send a test event

Use this before wiring real conversation or call events. The test endpoint signs a real HTTP POST and records the delivery result.

curl -X POST "https://api.ringnity.com/api/server/webhooks/test" \
  -H "Authorization: Bearer SERVER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "webhookId": "webhook-id",
    "event": "conversation.message.received"
  }'

Delivery headers

Use X-Ringnity-Delivery as your idempotency key. Automatic retry is deferred in preview; failed delivery attempts are recorded so you can inspect receiver errors before enabling real events.

X-Ringnity-Event: conversation.message.received
X-Ringnity-Delivery: evt_...
X-Ringnity-Timestamp: 1781107000
X-Ringnity-Signature: sha256=<hmac>

Read delivery logs

curl "https://api.ringnity.com/api/server/webhooks/deliveries?limit=10" \
  -H "Authorization: Bearer SERVER_API_KEY"

Contacts preview examples

List contacts

Use this from your backend when you need to compare CRM records with Ringnity contacts.

curl "https://api.ringnity.com/api/server/contacts?search=budi&limit=25" \
  -H "Authorization: Bearer SERVER_API_KEY"

Create or sync a contact

Send externalId from your CRM. If the same external id already exists, Ringnity updates that contact instead of creating a duplicate.

curl -X POST "https://api.ringnity.com/api/server/contacts" \
  -H "Authorization: Bearer SERVER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "crm-1001",
    "name": "Budi Santoso",
    "phone": "+62 812-3456-789",
    "email": "budi@example.com",
    "company": "Citibank",
    "tags": ["priority", "cardholder"],
    "notes": "Prefers chat"
  }'

Update a contact

Use the Ringnity contact id returned from list or create when you want to update a specific record.

curl -X PATCH "https://api.ringnity.com/api/server/contacts/contact-id" \
  -H "Authorization: Bearer SERVER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tags": ["priority", "renewal"],
    "notes": "Renewal follow-up scheduled"
  }'

Delete a contact

Delete stale or duplicated tenant contacts from your backend with the same server:contacts:write scope used for contact writes.

curl -X DELETE "https://api.ringnity.com/api/server/contacts/contact-id" \
  -H "Authorization: Bearer SERVER_API_KEY"

Common errors

These codes are safe to show in backend logs and make troubleshooting predictable.

401 SERVER_API_KEY_MISSING
401 SERVER_API_KEY_INVALID
403 SERVER_API_SCOPE_DENIED
400 SERVER_CONTACT_VALIDATION_FAILED
404 SERVER_CONTACT_NOT_FOUND
409 SERVER_CONTACT_CONFLICT

Report export examples

Export JSON

JSON export returns the full report envelope for back-office automation or BI ingestion.

curl "https://api.ringnity.com/api/server/reports/export?period=30days&format=json" \
  -H "Authorization: Bearer SERVER_API_KEY"

Export CSV

CSV export is useful for spreadsheet workflows and scheduled operational reports.

curl "https://api.ringnity.com/api/server/reports/export?period=30days&format=csv" \
  -H "Authorization: Bearer SERVER_API_KEY" \
  -o ringnity-report.csv

Build milestones

Auth foundation

Tenant-scoped server credentials, hashed keys, scopes, audit, and rate-limit hooks.

Contacts preview

Contact list/create/update/delete with pagination and tenant isolation.

Context token

Backend-issued context token for trusted Visitor SDK metadata.

Agent token

Backend-issued short-lived token for CRM or internal agent workspace reads.

Admin token

Backend-issued short-lived token for internal tenant admin portals.

Report export

Backend-readable report summaries, timeseries, and JSON or CSV exports.

Webhooks

Signed events for conversation, ticket, contact, and agent state changes.

Dashboard setup

Tenant admins can create backend-only keys in Dashboard > Developer > Server API. The raw key is shown once, then Ringnity keeps only the hash.

curl "https://api.ringnity.com/api/server/tenant/sdk-readiness" \
  -H "Authorization: Bearer SERVER_API_KEY"

Demo backend

The repository includes sun_demo_webhook, a Node.js demo backend that reads RINGNITY_SERVER_API_KEY and calls @ringnity/server-api to issue Agent SDK tokens.

curl "https://sadavir.id/ringnity/webhook/health"
curl -X POST "https://sadavir.id/ringnity/agent-token" \
  -H "Content-Type: application/json" \
  -d '{"username":"agent.one"}'