openapi: 3.2.0 info: title: Happyrobot Public SIP Trunks API description: Public API endpoints for Happyrobot version: 0.1.1 servers: - url: https://platform.happyrobot.ai/api/v2 security: - bearerAuth: [] tags: - name: SIP Trunks paths: /sip-trunks/: get: summary: List SIP trunks tags: - SIP Trunks description: Returns all SIP trunks for the organization. security: - bearerAuth: [] responses: '200': description: Default Response content: application/json: schema: type: array items: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ org_id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ number: type: string inbound_trunk_id: type: - string - 'null' outbound_trunk_id: type: - string - 'null' name: type: string created_at: type: string updated_at: type: string required: - id - org_id - number - inbound_trunk_id - outbound_trunk_id - name - created_at - updated_at additionalProperties: false '401': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false '500': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false post: summary: Create a SIP trunk tags: - SIP Trunks description: Creates a new SIP trunk with inbound and outbound LiveKit trunks. Rate limited to one creation every 10 minutes per organization. Send force=true in the body to bypass this limit (use with caution — each trunk has a recurring monthly cost). requestBody: content: application/json: schema: type: object properties: number: type: string minLength: 1 pattern: ^\+\d+$ name: type: string minLength: 1 address: type: string transport: default: udp type: string enum: - udp - tcp - tls auth_username: type: string auth_password: type: string allowed_addresses: type: array items: type: string minLength: 1 pattern: ^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\/(?:3[0-2]|[12]\d|[1-9]))?$ attributes_to_headers: type: object additionalProperties: type: string minLength: 1 pattern: ^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$ provider: type: string enum: - twilio - telnyx - custom direction: default: both type: string enum: - inbound - outbound - both tag_ids: type: array items: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ force: description: 'Set to true to bypass the 10-minute rate limit between SIP trunk creations. Use with caution: each SIP trunk incurs a recurring monthly cost.' type: boolean required: - number - name required: true security: - bearerAuth: [] responses: '201': description: Default Response content: application/json: schema: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ org_id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ number: type: string inbound_trunk_id: type: - string - 'null' outbound_trunk_id: type: - string - 'null' name: type: string created_at: type: string updated_at: type: string required: - id - org_id - number - inbound_trunk_id - outbound_trunk_id - name - created_at - updated_at additionalProperties: false '400': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false '401': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false '429': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false '500': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false /sip-trunks/options: get: summary: Get SIP trunk options tags: - SIP Trunks description: Returns trunk options for UI (id, name, number). security: - bearerAuth: [] responses: '200': description: Default Response content: application/json: schema: type: array items: type: object properties: id: type: string name: type: string number: type: string required: - id - name - number additionalProperties: false '401': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false '500': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false /sip-trunks/bulk: post: summary: Create multiple SIP trunks tags: - SIP Trunks description: Creates multiple SIP trunks from a shared configuration. Returns the successfully created trunks. Rate limited to one creation every 10 minutes per organization. Send force=true in the body to bypass this limit (use with caution — each trunk has a recurring monthly cost). requestBody: content: application/json: schema: type: object properties: numbers: minItems: 1 type: array items: type: string address: type: string transport: default: udp type: string enum: - udp - tcp - tls auth_username: type: string auth_password: type: string allowed_addresses: type: array items: type: string minLength: 1 pattern: ^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\/(?:3[0-2]|[12]\d|[1-9]))?$ attributes_to_headers: type: object additionalProperties: type: string minLength: 1 pattern: ^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$ direction: default: both type: string enum: - inbound - outbound - both tag_ids: type: array items: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ force: description: 'Set to true to bypass the 10-minute rate limit between SIP trunk creations. Use with caution: each SIP trunk incurs a recurring monthly cost.' type: boolean required: - numbers required: true security: - bearerAuth: [] responses: '201': description: Default Response content: application/json: schema: type: array items: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ org_id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ number: type: string inbound_trunk_id: type: - string - 'null' outbound_trunk_id: type: - string - 'null' name: type: string created_at: type: string updated_at: type: string required: - id - org_id - number - inbound_trunk_id - outbound_trunk_id - name - created_at - updated_at additionalProperties: false '400': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false '401': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false '429': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false '500': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false /sip-trunks/{id}: get: summary: Get a SIP trunk tags: - SIP Trunks description: Returns a single SIP trunk by ID. parameters: - schema: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ in: path name: id required: true description: SIP trunk ID security: - bearerAuth: [] responses: '200': description: Default Response content: application/json: schema: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ org_id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ number: type: string inbound_trunk_id: type: - string - 'null' outbound_trunk_id: type: - string - 'null' name: type: string created_at: type: string updated_at: type: string required: - id - org_id - number - inbound_trunk_id - outbound_trunk_id - name - created_at - updated_at additionalProperties: false '401': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false '404': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false '500': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false put: summary: Update a SIP trunk tags: - SIP Trunks description: Updates a SIP trunk by ID. requestBody: content: application/json: schema: type: object properties: number: type: string minLength: 1 pattern: ^\+\d+$ name: type: string minLength: 1 address: type: string transport: default: udp type: string enum: - udp - tcp - tls auth_username: type: string auth_password: type: string allowed_addresses: type: array items: type: string minLength: 1 pattern: ^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\/(?:3[0-2]|[12]\d|[1-9]))?$ attributes_to_headers: type: object additionalProperties: type: string minLength: 1 pattern: ^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$ provider: type: string enum: - twilio - telnyx - custom direction: default: both type: string enum: - inbound - outbound - both tag_ids: type: array items: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ force: description: 'Set to true to bypass the 10-minute rate limit between SIP trunk creations. Use with caution: each SIP trunk incurs a recurring monthly cost.' type: boolean parameters: - schema: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ in: path name: id required: true description: SIP trunk ID security: - bearerAuth: [] responses: '200': description: Default Response content: application/json: schema: type: object properties: id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ org_id: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ number: type: string inbound_trunk_id: type: - string - 'null' outbound_trunk_id: type: - string - 'null' name: type: string created_at: type: string updated_at: type: string required: - id - org_id - number - inbound_trunk_id - outbound_trunk_id - name - created_at - updated_at additionalProperties: false '401': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false '404': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false '500': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false delete: summary: Delete a SIP trunk tags: - SIP Trunks description: Deletes a SIP trunk by ID. Fails if the trunk is still in use by a workflow. parameters: - schema: type: string format: uuid pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$ in: path name: id required: true description: SIP trunk ID security: - bearerAuth: [] responses: '204': description: Deleted content: application/json: schema: description: Deleted '400': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false '401': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false '404': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false '500': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string statusCode: type: integer minimum: -9007199254740991 maximum: 9007199254740991 details: {} required: - error additionalProperties: false components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: Opaque