Twilio
Twilio Error 12300 means your webhook returned a Content-Type Twilio can't process. Return text/xml for TwiML and a supported audio MIME type for Play.
Updated Jul 1, 2026
The short answer
Twilio Error 12300 "Invalid Content-Type" means Twilio fetched your webhook (or media) URL but the response's Content-Type header is one it cannot process for that context. Fix it by returning text/xml or application/xml for TwiML, returning a supported audio MIME type (e.g. audio/mpeg, audio/wav) for the <Play> verb, and always sending a Content-Type header so the request isn't treated as 502.
Twilio raises Error 12300 — Invalid Content-Type when it makes an HTTP request to one of your URLs (a voice/messaging webhook, an action/StatusCallback URL, or a media URL referenced by <Play>) and the response comes back with a Content-Type header that is invalid for how Twilio intends to use it. Twilio decides how to interpret your response based on this header, so a mismatch — for example serving TwiML as application/json or pointing <Play> at an XML document — stops it cold.
There are two distinct mismatches behind almost every 12300:
text/xml or application/xml (it also accepts text/html). A common trap is a framework or serializer that emits application/json by default — e.g. ASP.NET Web API without XML formatters configured, or an Express handler that calls res.json() or passes a JS object to res.send() instead of sending a raw XML string with an explicit Content-Type: text/xml header. The body may be valid XML, but the header tells Twilio it's JSON, so it refuses to parse it.<Play> verb points at non-audio content. <Play> requires the fetched file to be served with a supported audio MIME type. Pointing it at an XML/TwiML document, an HTML error page, or a file your storage host serves as application/octet-stream/text/plain triggers 12300.A related failure: returning no Content-Type header at all. Twilio surfaces those requests in the Debugger as a 502 Bad Gateway rather than 12300, but the underlying cause is the same — set the header explicitly.
Per Twilio's <Play> documentation, the supported audio MIME types are: audio/mpeg, audio/wav, audio/wave, audio/x-wav, audio/aiff, audio/x-aifc, audio/x-aiff, audio/x-gsm, audio/gsm, and audio/ulaw.
<Play> media URL.Content-Type: text/xml (or application/xml) explicitly rather than relying on a JSON-by-default serializer. Most server SDKs do this for you when you return a VoiceResponse/MessagingResponse object instead of a hand-built string.HTTP/1.1 200 OKContent-Type: text/xml<?xml version="1.0" encoding="UTF-8"?><Response><Say>Thanks for calling.</Say></Response>
<Play>, verify the media URL serves a supported audio type. Open the URL directly and check the response header (curl -I <url>). If your object store (S3, IBM Cloud Object Storage, etc.) serves the file as application/octet-stream or text/plain, set the object's Content-Type metadata to the correct audio type, e.g. audio/mpeg for an MP3.200 OK with no body is documented as sufficient. For incoming message/voice webhooks that expect a TwiML response, Twilio's own guidance is to return 200 OK with Content-Type: text/xml and an empty <Response/> body.If you send through Courier and route SMS/voice via a Twilio integration, the TwiML/media responses still originate from your own endpoints — apply the same Content-Type fixes there; Courier does not rewrite the headers your server returns.
References
FAQ
Twilio decides how to parse your response from the Content-Type header, not the body. If your server sends valid TwiML but labels it application/json (a common framework default), Twilio rejects it with 12300. Set the header to text/xml or application/xml.
One API, every provider
Courier connects to your email, SMS, and push providers, handles retries and failover, and surfaces delivery errors in plain language.
Last reviewed Jul 1, 2026. Courier is not affiliated with third-party providers; error behavior may vary by implementation.
© 2026 Courier. All rights reserved.