Twilio
Twilio API integration with managed OAuth. SMS, voice calls, phone numbers, and communications. Use this skill when users want to send SMS messages, make voice calls, manage phone numbers, or work wit
Twilio API integration with managed OAuth. SMS, voice calls, phone numbers, and communications. Use this skill when users want to send SMS messages, make voice calls, manage phone numbers, or work wit
Real data. Real impact.
Emerging
Developers
Per week
Open source
Skills give you superpowers. Install in 30 seconds.
Access the Twilio API with managed OAuth authentication. Send SMS messages, make voice calls, manage phone numbers, and work with Twilio resources.
# List all accounts python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/twilio/2010-04-01/Accounts.json') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
https://gateway.maton.ai/twilio/2010-04-01/Accounts/{AccountSid}/{resource}.json
The gateway proxies requests to
api.twilio.com and automatically injects your OAuth token.
Important: Most Twilio endpoints require your Account SID in the path. You can get your Account SID from the
/Accounts.json endpoint.
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as
MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Manage your Twilio OAuth connections at
https://ctrl.maton.ai.
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections?app=twilio&status=ACTIVE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
python <<'EOF' import urllib.request, os, json data = json.dumps({'app': 'twilio'}).encode() req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Content-Type', 'application/json') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
Response:
{ "connection": { "connection_id": "ebe566b1-3eaf-4926-bc92-0d8d47445f12", "status": "ACTIVE", "creation_time": "2026-02-09T23:18:44.243582Z", "last_updated_time": "2026-02-09T23:19:55.176687Z", "url": "https://connect.maton.ai/?session_token=...", "app": "twilio", "metadata": {} } }
Open the returned
url in a browser to complete OAuth authorization.
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
If you have multiple Twilio connections, specify which one to use with the
Maton-Connection header:
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/twilio/2010-04-01/Accounts.json') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Maton-Connection', 'ebe566b1-3eaf-4926-bc92-0d8d47445f12') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
If omitted, the gateway uses the default (oldest) active connection.
GET /twilio/2010-04-01/Accounts.json
Response:
{ "accounts": [ { "sid": "ACf5d980cd4b3f7604a464afaec191fc60", "friendly_name": "My first Twilio account", "status": "active", "date_created": "Mon, 09 Feb 2026 20:19:55 +0000", "date_updated": "Mon, 09 Feb 2026 20:20:05 +0000" } ] }
GET /twilio/2010-04-01/Accounts/{AccountSid}.json
GET /twilio/2010-04-01/Accounts/{AccountSid}/Messages.json
Query Parameters:
PageSize - Number of results per page (default: 50)To - Filter by recipient phone numberFrom - Filter by sender phone numberDateSent - Filter by date sentResponse:
{ "messages": [ { "sid": "SMxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "body": "Hello!", "from": "+15551234567", "to": "+15559876543", "status": "delivered", "date_sent": "Mon, 09 Feb 2026 21:00:00 +0000" } ], "page": 0, "page_size": 50 }
GET /twilio/2010-04-01/Accounts/{AccountSid}/Messages/{MessageSid}.json
POST /twilio/2010-04-01/Accounts/{AccountSid}/Messages.json Content-Type: application/x-www-form-urlencodedTo=+15559876543&From=+15551234567&Body=Hello%20from%20Twilio!
Required Parameters:
To - Recipient phone number (E.164 format)From - Twilio phone number or messaging service SIDBody - Message text (max 1600 characters)Optional Parameters:
MessagingServiceSid - Use instead of From for message routingMediaUrl - URL of media to send (MMS)StatusCallback - Webhook URL for status updatesResponse:
{ "sid": "SMxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "body": "Hello from Twilio!", "from": "+15551234567", "to": "+15559876543", "status": "queued", "date_created": "Mon, 09 Feb 2026 21:00:00 +0000" }
POST /twilio/2010-04-01/Accounts/{AccountSid}/Messages/{MessageSid}.json Content-Type: application/x-www-form-urlencodedBody=
Setting Body to empty string redacts the message content.
DELETE /twilio/2010-04-01/Accounts/{AccountSid}/Messages/{MessageSid}.json
Returns 204 No Content on success.
GET /twilio/2010-04-01/Accounts/{AccountSid}/Calls.json
Query Parameters:
PageSize - Results per pageStatus - Filter by status (queued, ringing, in-progress, completed, etc.)To - Filter by recipientFrom - Filter by callerResponse:
{ "calls": [ { "sid": "CAxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "from": "+15551234567", "to": "+15559876543", "status": "completed", "duration": "60", "direction": "outbound-api" } ], "page": 0, "page_size": 50 }
GET /twilio/2010-04-01/Accounts/{AccountSid}/Calls/{CallSid}.json
POST /twilio/2010-04-01/Accounts/{AccountSid}/Calls.json Content-Type: application/x-www-form-urlencodedTo=+15559876543&From=+15551234567&Url=https://example.com/twiml
Required Parameters:
To - Recipient phone numberFrom - Twilio phone numberUrl - TwiML application URLOptional Parameters:
StatusCallback - Webhook URL for call status updatesStatusCallbackEvent - Events to receive (initiated, ringing, answered, completed)Timeout - Seconds to wait for answer (default: 60)Record - Set to true to record the callPOST /twilio/2010-04-01/Accounts/{AccountSid}/Calls/{CallSid}.json Content-Type: application/x-www-form-urlencodedStatus=completed
Use
Status=completed to end an in-progress call.
DELETE /twilio/2010-04-01/Accounts/{AccountSid}/Calls/{CallSid}.json
GET /twilio/2010-04-01/Accounts/{AccountSid}/IncomingPhoneNumbers.json
Response:
{ "incoming_phone_numbers": [ { "sid": "PNxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "phone_number": "+15551234567", "friendly_name": "My Number", "capabilities": { "voice": true, "sms": true, "mms": true } } ] }
GET /twilio/2010-04-01/Accounts/{AccountSid}/IncomingPhoneNumbers/{PhoneNumberSid}.json
POST /twilio/2010-04-01/Accounts/{AccountSid}/IncomingPhoneNumbers/{PhoneNumberSid}.json Content-Type: application/x-www-form-urlencodedFriendlyName=Updated%20Name&VoiceUrl=https://example.com/voice
DELETE /twilio/2010-04-01/Accounts/{AccountSid}/IncomingPhoneNumbers/{PhoneNumberSid}.json
GET /twilio/2010-04-01/Accounts/{AccountSid}/Applications.json
Response:
{ "applications": [ { "sid": "APxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "friendly_name": "My App", "voice_url": "https://example.com/voice", "sms_url": "https://example.com/sms" } ] }
GET /twilio/2010-04-01/Accounts/{AccountSid}/Applications/{ApplicationSid}.json
POST /twilio/2010-04-01/Accounts/{AccountSid}/Applications.json Content-Type: application/x-www-form-urlencodedFriendlyName=My%20App&VoiceUrl=https://example.com/voice
Response:
{ "sid": "APxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "friendly_name": "My App", "voice_url": "https://example.com/voice", "date_created": "Tue, 10 Feb 2026 00:20:15 +0000" }
POST /twilio/2010-04-01/Accounts/{AccountSid}/Applications/{ApplicationSid}.json Content-Type: application/x-www-form-urlencodedFriendlyName=Updated%20App%20Name
DELETE /twilio/2010-04-01/Accounts/{AccountSid}/Applications/{ApplicationSid}.json
Returns 204 No Content on success.
GET /twilio/2010-04-01/Accounts/{AccountSid}/Queues.json
Response:
{ "queues": [ { "sid": "QUxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "friendly_name": "Support Queue", "current_size": 0, "max_size": 1000, "average_wait_time": 0 } ] }
POST /twilio/2010-04-01/Accounts/{AccountSid}/Queues.json Content-Type: application/x-www-form-urlencodedFriendlyName=Support%20Queue&MaxSize=100
POST /twilio/2010-04-01/Accounts/{AccountSid}/Queues/{QueueSid}.json Content-Type: application/x-www-form-urlencodedFriendlyName=Updated%20Queue%20Name
DELETE /twilio/2010-04-01/Accounts/{AccountSid}/Queues/{QueueSid}.json
GET /twilio/2010-04-01/Accounts/{AccountSid}/Addresses.json
POST /twilio/2010-04-01/Accounts/{AccountSid}/Addresses.json Content-Type: application/x-www-form-urlencodedFriendlyName=Office&Street=123%20Main%20St&City=San%20Francisco&Region=CA&PostalCode=94105&IsoCountry=US&CustomerName=Acme%20Inc
GET /twilio/2010-04-01/Accounts/{AccountSid}/Usage/Records.json
Query Parameters:
Category - Filter by usage category (calls, sms, etc.)StartDate - Start date (YYYY-MM-DD)EndDate - End date (YYYY-MM-DD)Response:
{ "usage_records": [ { "category": "sms", "description": "SMS Messages", "count": "100", "price": "0.75", "start_date": "2026-02-01", "end_date": "2026-02-28" } ] }
Twilio uses page-based pagination:
GET /twilio/2010-04-01/Accounts/{AccountSid}/Messages.json?PageSize=50&Page=0
Parameters:
PageSize - Results per page (default: 50)Page - Page number (0-indexed)Response includes:
{ "messages": [...], "page": 0, "page_size": 50, "first_page_uri": "/2010-04-01/Accounts/{AccountSid}/Messages.json?PageSize=50&Page=0", "next_page_uri": "/2010-04-01/Accounts/{AccountSid}/Messages.json?PageSize=50&Page=1", "previous_page_uri": null }
Use
next_page_uri to fetch the next page of results.
const response = await fetch( 'https://gateway.maton.ai/twilio/2010-04-01/Accounts.json', { headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}` } } ); const data = await response.json(); const accountSid = data.accounts[0].sid; console.log(`Account SID: ${accountSid}`);
import os import requestsGet account SID
response = requests.get( 'https://gateway.maton.ai/twilio/2010-04-01/Accounts.json', headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'} ) account_sid = response.json()['accounts'][0]['sid'] print(f"Account SID: {account_sid}")
import os import requestsaccount_sid = 'ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
response = requests.post( f'https://gateway.maton.ai/twilio/2010-04-01/Accounts/{account_sid}/Messages.json', headers={ 'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}', 'Content-Type': 'application/x-www-form-urlencoded' }, data={ 'To': '+15559876543', 'From': '+15551234567', 'Body': 'Hello from Python!' } ) message = response.json() print(f"Message SID: {message['sid']}") print(f"Status: {message['status']}")
import os import requestsaccount_sid = 'ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
response = requests.post( f'https://gateway.maton.ai/twilio/2010-04-01/Accounts/{account_sid}/Calls.json', headers={ 'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}', 'Content-Type': 'application/x-www-form-urlencoded' }, data={ 'To': '+15559876543', 'From': '+15551234567', 'Url': 'https://demo.twilio.com/docs/voice.xml' } ) call = response.json() print(f"Call SID: {call['sid']}") print(f"Status: {call['status']}")
/2010-04-01/ API version prefixapplication/x-www-form-urlencoded format (not JSON)ACSM (SMS) or MM (MMS)CAPNAPQUjq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments| Status | Meaning |
|---|---|
| 400 | Missing Twilio connection or bad request |
| 401 | Invalid or missing Maton API key |
| 404 | Resource not found |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Twilio API |
Twilio error responses include:
{ "code": 20404, "message": "The requested resource was not found", "more_info": "https://www.twilio.com/docs/errors/20404", "status": 404 }
When you receive an "Invalid API key" error, ALWAYS follow these steps before concluding there is an issue:
MATON_API_KEY environment variable is set:echo $MATON_API_KEY
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
No automatic installation available. Please visit the source repository for installation instructions.
View Installation Instructions1,500+ AI skills, agents & workflows. Install in 30 seconds. Part of the Torly.ai family.
© 2026 Torly.ai. All rights reserved.