Documentation/API Reference

    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

    API key or OAuth 2.0 authentication

    Fast

    Low latency with global CDN

    Base URL#

    text
    Workspace API: http://127.0.0.1:43131/api/v1

    Note

    Use the sandbox environment for testing. Sandbox data is separate and reset weekly.

    Authentication#

    Authenticate API requests using an API key or OAuth 2.0:

    API Key Authentication
    curl -X GET "http://127.0.0.1:43131/api/v1/conversations" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "X-Account-ID: your_account_id"

    Getting your API key:

    1. Navigate to Settings → API
    2. Click "Generate API Key"
    3. Name your key (e.g., "Production Integration")
    4. Set permissions (read-only or read-write)
    5. Copy the key (shown only once)
    6. Store securely - treat like a password

    Warning

    Never commit API keys to version control or expose them in client-side code. Rotate keys regularly and revoke compromised keys immediately.

    Rate Limits#

    API requests are rate-limited to ensure service reliability.

    Current Limits#

    Starter

    Sustained: 100 requests/minute
    Burst: 10 requests/second

    Business

    Sustained: 500 requests/minute
    Burst: 50 requests/second

    Enterprise

    Sustained: Custom (contact sales)
    Burst: Custom

    Rate limits are per API key. Headers in responses indicate your current status:

    text
    X-RateLimit-Limit: 100
    X-RateLimit-Remaining: 87
    X-RateLimit-Reset: 1640995200

    Tip

    When you hit the rate limit, you'll receive a 429 status code. Implement exponential backoff and respect the `Retry-After` header.

    Endpoints Overview#

    Core API endpoints organized by resource type.

    Conversations

    Create, retrieve, update, and delete conversations

    GET/conversationsList all conversations
    GET/conversations/:idGet conversation details
    POST/conversationsCreate conversation
    PATCH/conversations/:idUpdate conversation
    DELETE/conversations/:idDelete conversation

    Insights

    Access AI-generated insights and analytics

    GET/insightsList all insights
    GET/insights/:idGet specific insight
    GET/insights/trendsGet trend data
    GET/insights/summaryGet summary statistics

    Action Items

    Manage tasks and follow-ups

    GET/action-itemsList action items
    GET/action-items/:idGet action item details
    PATCH/action-items/:idUpdate action item
    POST/action-itemsCreate action item

    Workspace Access

    Manage users, teams, departments, and scoped manager assignments

    GET/usersList users with role context
    PATCH/users/:userId/detailsUpdate user profile fields (admin)
    PATCH/users/:userId/roleUpdate account role
    PATCH/users/:userId/teamSet primary team membership
    GET/teams/:teamId/managersList team managers
    POST/teams/:teamId/managersAssign team manager
    DELETE/teams/:teamId/managers/:userIdRemove team manager
    GET/departments/:id/managersList department managers
    POST/departments/:id/managersAssign department manager
    DELETE/departments/:id/managers/:userIdRemove department manager

    Note

    Workspace access endpoints require account context (`X-Account-ID`) and are permission-gated. Team and department manager assignments are scoped; they do not change account-wide role membership.

    Conversations API#

    Comprehensive examples for working with conversations.

    List Conversations#

    Request
    GET /api/v1/conversations?limit=20&offset=0&department=sales
    
    curl -X GET "http://127.0.0.1:43131/api/v1/conversations?limit=20" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "X-Account-ID: your_account_id"
    Response
    {
      "data": [
        {
          "id": "conv_abc123",
          "title": "Q1 Planning with Acme Corp",
          "date": "2024-01-15T10:30:00Z",
          "duration": 3600,
          "department": "sales",
          "participants": [
            {
              "id": "user_123",
              "name": "John Smith",
              "email": "[email protected]"
            }
          ],
          "status": "processed",
          "summary": "Discussed Q1 product roadmap and pricing...",
          "sentiment": {
            "score": 0.85,
            "label": "positive"
          },
          "recording_url": "https://...",
          "transcript_url": "https://...",
          "created_at": "2024-01-15T10:00:00Z",
          "updated_at": "2024-01-15T11:00:00Z"
        }
      ],
      "pagination": {
        "total": 150,
        "limit": 20,
        "offset": 0,
        "has_more": true
      }
    }

    Query Parameters:

    limitinteger
    Number of results (max 100)(default: 20)
    offsetinteger
    Pagination offset(default: 0)
    departmentstring
    Filter by department
    start_datedate
    Filter from date (YYYY-MM-DD)
    end_datedate
    Filter to date (YYYY-MM-DD)
    statusstring
    Filter by status (processing, processed, failed)

    Create Conversation#

    Request
    POST /api/v1/conversations
    
    curl -X POST "http://127.0.0.1:43131/api/v1/conversations" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "X-Account-ID: your_account_id" \
      -H "Content-Type: application/json" \
      -d '{
        "title": "Client Discovery Call",
        "date": "2024-01-15T14:00:00Z",
        "department": "sales",
        "participants": [
          {
            "name": "Jane Client",
            "email": "[email protected]"
          }
        ],
        "recording_url": "https://example.com/recording.mp4",
        "auto_process": true
      }'
    Response
    {
      "id": "conv_xyz789",
      "title": "Client Discovery Call",
      "status": "processing",
      "created_at": "2024-01-15T14:05:00Z",
      "estimated_completion": "2024-01-15T14:10:00Z"
    }

    Insights API#

    Get Insights#

    Request
    GET /api/v1/insights?conversation_id=conv_abc123
    
    curl -X GET "http://127.0.0.1:43131/api/v1/insights?conversation_id=conv_abc123" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "X-Account-ID: your_account_id"
    Response
    {
      "data": [
        {
          "id": "insight_123",
          "conversation_id": "conv_abc123",
          "type": "action_item",
          "content": "Send product specs to John by Friday",
          "assigned_to": "user_456",
          "due_date": "2024-01-20",
          "status": "pending",
          "confidence": 0.92,
          "created_at": "2024-01-15T11:00:00Z"
        },
        {
          "id": "insight_124",
          "conversation_id": "conv_abc123",
          "type": "topic",
          "content": "Pricing Discussion",
          "keywords": ["pricing", "discount", "annual contract"],
          "relevance_score": 0.88
        },
        {
          "id": "insight_125",
          "conversation_id": "conv_abc123",
          "type": "decision",
          "content": "Agreed to proceed with Enterprise plan",
          "participants": ["user_123", "user_456"]
        }
      ]
    }

    Webhooks#

    Receive real-time notifications when events occur. See Integrations → Webhooks for setup.

    Webhook Payload Structure#

    Example Webhook
    {
      "event": "conversation.processed",
      "timestamp": "2024-01-15T11:00:00Z",
      "account_id": "acc_123",
      "data": {
        "conversation_id": "conv_xyz789",
        "title": "Client Discovery Call",
        "status": "processed",
        "duration": 1800,
        "processing_time": 120,
        "insights_count": 8,
        "action_items_count": 3
      },
      "webhook_id": "wh_abc123",
      "delivery_id": "del_456"
    }

    Error Handling#

    The API uses standard HTTP status codes and returns error details in JSON format.

    HTTP Status Codes#

    200

    OK

    Request succeeded

    201

    Created

    Resource created successfully

    400

    Bad Request

    Invalid request parameters

    401

    Unauthorized

    Invalid or missing API key

    403

    Forbidden

    Insufficient permissions

    404

    Not Found

    Resource not found

    429

    Too Many Requests

    Rate limit exceeded

    500

    Internal Server Error

    Server error

    Error Response Format#

    Error Response
    {
      "error": {
        "code": "invalid_parameter",
        "message": "The 'date' field must be in ISO 8601 format",
        "param": "date",
        "type": "validation_error",
        "docs_url": "http://127.0.0.1:43131/documentation/api#errors"
      }
    }

    Common Error Codes:

    invalid_parameterRequest parameter is invalid or missing
    authentication_failedAPI key is invalid or expired
    rate_limit_exceededToo many requests in time window
    resource_not_foundRequested resource doesn't exist
    insufficient_permissionsAPI key lacks required permissions

    Retry Logic#

    Implement exponential backoff for failed requests:

    Retry Example (Node.js)
    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#

    Complete Example
    const axios = require('axios');
    
    const API_KEY = process.env.MEETRIC_API_KEY;
    const ACCOUNT_ID = process.env.MEETRIC_ACCOUNT_ID;
    const BASE_URL = 'http://127.0.0.1:43131/api/v1';
    
    const Meetric = axios.create({
      baseURL: BASE_URL,
      headers: {
        'Authorization': `Bearer ${API_KEY}`,
        'X-Account-ID': ACCOUNT_ID,
        'Content-Type': 'application/json'
      }
    });
    
    // List conversations
    async function getConversations() {
      try {
        const response = await Meetric.get('/conversations', {
          params: {
            limit: 10,
            department: 'sales'
          }
        });
        return response.data;
      } catch (error) {
        console.error('Error:', error.response?.data || error.message);
        throw error;
      }
    }
    
    // Create conversation
    async function createConversation(data) {
      try {
        const response = await Meetric.post('/conversations', data);
        console.log('Created:', response.data);
        return response.data;
      } catch (error) {
        console.error('Error:', error.response?.data || error.message);
        throw error;
      }
    }
    
    // Usage
    (async () => {
      const conversations = await getConversations();
      console.log('Found', conversations.pagination.total, 'conversations');
    })();

    Python Example#

    Complete Example
    import requests
    import os
    
    API_KEY = os.environ['MEETRIC_API_KEY']
    ACCOUNT_ID = os.environ['MEETRIC_ACCOUNT_ID']
    BASE_URL = 'http://127.0.0.1:43131/api/v1'
    
    class MeetricClient:
        def __init__(self, api_key, account_id):
            self.session = requests.Session()
            self.session.headers.update({
                'Authorization': f'Bearer {api_key}',
                'X-Account-ID': account_id,
                '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 create_conversation(self, data):
            response = self.session.post(
                f'{self.base_url}/conversations',
                json=data
            )
            response.raise_for_status()
            return response.json()
    
    # Usage
    client = MeetricClient(API_KEY, ACCOUNT_ID)
    
    # List conversations
    conversations = client.get_conversations({
        'limit': 10,
        'department': 'sales'
    })
    print(f"Found {conversations['pagination']['total']} conversations")
    
    # Create conversation
    new_conv = client.create_conversation({
        'title': 'Client Call',
        'date': '2024-01-15T14:00:00Z',
        'department': 'sales'
    })
    print(f"Created: {new_conv['id']}")

    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

    Questions about the API? Email [email protected] or join our developer community on Discord.