API Reference
Build custom integrations and automate workflows with Meetric's REST API. Access conversations, insights and more programmatically.
Getting Started#
RESTful
Standard HTTP methods and JSON responses
Secure
Token-based authentication with scoped access
Fast
Low latency with global CDN
Base URL#
REST API: http://127.0.0.1:44449/api/v1/restAuthoritative API schema:
OpenAPI spec: http://127.0.0.1:44449/api/v1/rest/openapi.jsonNote
Authentication#
Authenticate REST API requests with an API token:
curl -X GET "http://127.0.0.1:44449/api/v1/rest/conversations" \
-H "Authorization: Bearer mt_your_api_token"Getting your API key:
- Navigate to Settings → API and open the API tokens section
- Click "Create API Token"
- Name your key (e.g., "Production Integration")
- Select token scopes (for example conversations, transcripts, insights)
- Copy the key (shown only once)
- Store securely - treat like a password
Warning
Rate Limits#
API tokens enforce per-token rate limits and daily conversation quotas.
Current Limits#
API Token Defaults
Limits are configured per token. The API returns HTTP 429 when the per-minute limit is hit:
{
"statusCode": 429,
"message": "Rate limit exceeded. Please try again later.",
"retryAfter": 60
}Tip
Endpoints Overview#
Partner REST API endpoints organized by capability.
Conversations
Read conversation data with token scopes and filters
/rest/conversationsList conversations (cursor pagination)/rest/conversations/:idGet conversation details/rest/conversations/:id/transcriptGet transcript (scope: transcripts)/rest/conversations/:id/insightsGet insights (scope: insights)/rest/conversations/:id/recording-urlGet recording URL (scope: recordings)Reference Data
Fetch account-scoped directory entities
/rest/accountGet account and branding context/rest/usersList users (scope: users)/rest/teamsList teams (scope: teams)/rest/departmentsList departments (scope: departments)Webhooks
Inspect delivery status for token webhooks
/rest/webhooks/deliveriesList recent webhook deliveriesNote
Conversations API#
Comprehensive examples for working with conversations.
List Conversations#
GET /api/v1/rest/conversations?limit=25&department_id=<department_uuid>
curl -X GET "http://127.0.0.1:44449/api/v1/rest/conversations?limit=25" \
-H "Authorization: Bearer mt_your_api_token"{
"conversations": [
{
"id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"title": "Discovery call - Acme",
"company": "Acme",
"date": "2024-01-15T10:30:00Z",
"duration": 3600,
"medium": "call",
"sentiment": "positive",
"conversation_type": "sales",
"department": {
"id": "11111111-0000-0000-0000-000000000001",
"name": "B2B Sales"
},
"user": {
"id": "67c869eb-30b1-4eb3-bd2c-be8c912a9827",
"name": "Erik Lindstrom",
"email": "[email protected]"
}
}
],
"pagination": {
"has_more": false,
"next_cursor": null,
"limit": 25
},
"_meta": {
"token_prefix": "mt_ab12cd34",
"timestamp": "2026-02-08T00:00:00.000Z"
}
}Query Parameters:
limitintegercursorstringdepartment_iduuidmediumstringdate_fromdatetimedate_todatetimeuser_iduuidInsights API#
Get Conversation Insights#
GET /api/v1/rest/conversations/:id/insights
curl -X GET "http://127.0.0.1:44449/api/v1/rest/conversations/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/insights" \
-H "Authorization: Bearer mt_your_api_token"{
"conversation_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"insights": [
{
"id": "99999999-aaaa-bbbb-cccc-dddddddddddd",
"insight_type": "kpi",
"insight_text": "Customer requested SSO.",
"kpi_slug": "sso",
"kpi_label": "SSO",
"impact": "high",
"start_time_seconds": 120,
"end_time_seconds": 165,
"message_index": 14
}
],
"_meta": {
"token_prefix": "mt_ab12cd34",
"timestamp": "2026-02-08T00:00:00.000Z"
}
}Note
include_insights=true onGET /rest/conversations/:id when the token includes the insights scope.Webhooks#
Receive real-time notifications when events occur. Configure webhook URLs from the API settings tab in Settings when creating or managing API tokens.
Webhook Payload Structure#
X-Webhook-Signature: sha256=<HMAC signature>
X-Webhook-Event: conversation.completed
X-Webhook-Delivery-Id: <delivery uuid>
X-Webhook-Timestamp: <unix timestamp>{
"event": "conversation.completed",
"timestamp": "2024-01-15T11:00:00Z",
"data": {
"conversation": {
"id": "conv_xyz789",
"title": "Client Discovery Call",
"date": "2024-01-15T10:30:00Z",
"duration": 1800,
"medium": "call",
"conversation_type": "sales",
"summary": "Summary text...",
"participants": [
{
"name": "Jane Client",
"email": "[email protected]",
"role": "customer"
}
]
}
},
"_meta": {
"token_prefix": "mt_ab12cd34",
"delivery_id": "del_456"
}
}Error Handling#
The API uses standard HTTP status codes and returns error details in JSON format.
HTTP Status Codes#
OK
Request succeeded
Created
Resource created successfully
Bad Request
Invalid request parameters
Unauthorized
Invalid, missing, inactive or expired API token
Forbidden
Insufficient permissions
Not Found
Resource not found
Too Many Requests
Rate limit exceeded
Internal Server Error
Server error
Error Response Format#
{
"statusCode": 400,
"message": "Account ID is required",
"error": "Bad Request"
}Common error messages:
Invalid API tokenBearer token is unknownAPI token has been revokedToken was revoked and can no longer be usedToken does not have the required scopeToken scope is missing for the endpointDaily quota exceededToken reached the daily unique conversation quotaConversation not foundResource is missing or outside token/account scopeRetry Logic#
Implement exponential backoff for failed requests:
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = await fetch(url, options);
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || Math.pow(2, attempt);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
continue;
}
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return await response.json();
} catch (error) {
if (attempt === maxRetries - 1) throw error;
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}Code Examples#
Node.js Example#
const axios = require('axios');
const API_TOKEN = process.env.MEETRIC_API_TOKEN;
const BASE_URL = 'http://127.0.0.1:44449/api/v1/rest';
const Meetric = axios.create({
baseURL: BASE_URL,
headers: {
'Authorization': `Bearer ${API_TOKEN}`,
'Content-Type': 'application/json'
}
});
// List conversations with cursor pagination
async function getConversations() {
try {
const response = await Meetric.get('/conversations', {
params: {
limit: 25,
date_from: '2026-01-01T00:00:00.000Z'
}
});
return response.data;
} catch (error) {
console.error('Error:', error.response?.data || error.message);
throw error;
}
}
(async () => {
const conversations = await getConversations();
const first = conversations.conversations?.[0];
if (first) {
const insights = await Meetric.get(`/conversations/${first.id}/insights`);
console.log('Insights count:', insights.data.insights?.length || 0);
}
})();Python Example#
import requests
import os
API_TOKEN = os.environ['MEETRIC_API_TOKEN']
BASE_URL = 'http://127.0.0.1:44449/api/v1/rest'
class MeetricClient:
def __init__(self, api_token):
self.session = requests.Session()
self.session.headers.update({
'Authorization': f'Bearer {api_token}',
'Content-Type': 'application/json'
})
self.base_url = BASE_URL
def get_conversations(self, params=None):
response = self.session.get(
f'{self.base_url}/conversations',
params=params
)
response.raise_for_status()
return response.json()
def get_insights(self, conversation_id):
response = self.session.get(
f'{self.base_url}/conversations/{conversation_id}/insights'
)
response.raise_for_status()
return response.json()
client = MeetricClient(API_TOKEN)
# List conversations
conversations = client.get_conversations({
'limit': 25,
'medium': 'call'
})
first = conversations.get('conversations', [None])[0]
if first:
insights = client.get_insights(first['id'])
print(f"Found {len(insights.get('insights', []))} insights")Best Practices#
Use Pagination
Always paginate large result sets to avoid timeouts and reduce memory usage
Cache Responses
Cache API responses when data doesn't change frequently to reduce API calls
Handle Errors Gracefully
Implement proper error handling and retry logic with exponential backoff
Secure API Keys
Never expose API keys in client-side code or commit them to version control
Use Webhooks
For real-time updates, use webhooks instead of polling the API repeatedly
Version Your API Calls
Specify API version in requests to ensure compatibility with future changes
Note