Skip to content

JSON-body endpoints (Content API, Messaging v2) send camelCase request keys verbatim — request types don't match the snake_case wire format #1190

Description

@simllll

Description

For endpoints whose request bodies are sent as application/json (e.g. Content API content.v1.contents.create(), Messaging v2 messaging.v2.channelsSenders(sid).update()), the generated client sends the params object verbatim (data = params) and never converts the camelCase TypeScript property names to the snake_case keys the REST API expects. Because the generated request types are also camelCase, typed code compiles cleanly but produces an invalid request body on the wire.

Form-encoded endpoints are not affected: their generated code explicitly maps each field, e.g. in trunking/v1/trunk.js:

data["FriendlyName"] = params["friendlyName"];
headers["Content-Type"] = "application/x-www-form-urlencoded";

The JSON endpoints instead do:

data = params;
headers["Content-Type"] = "application/json";

Reproduction (no network needed)

import twilio from "twilio";
const client = twilio("ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "fake_token");

client.httpClient.axios.interceptors.request.use((c) => {
  console.log(`${c.method.toUpperCase()} ${c.url}`);
  console.log(`Body: ${typeof c.data === "string" ? c.data : JSON.stringify(c.data)}`);
  return Promise.reject(new Error("stop-before-network"));
});

await client.content.v1.contents.create({
  friendlyName: "qr",
  language: "en",
  types: { twilioQuickReply: { body: "Pick", actions: [{ id: "a", title: "Yes" }] } },
}).catch(() => {});

Output (twilio@6.0.2, node 22):

POST https://content.twilio.com/v1/Content
Body: {"friendlyName":"qr","language":"en","types":{"twilioQuickReply":{"body":"Pick","actions":[{"id":"a","title":"Yes"}]}}}

Sending that body to the real API returns Invalid types. At least one content type definition is required, because the Content API expects friendly_name and the content-type key twilio/quick-reply. The same pattern on channelsSenders().update({ webhook: { callbackUrl, callbackMethod } }) returns error 63100 Update request body is empty (it expects callback_url / callback_method).

Expected

Either (a) the serializer converts camelCase request properties to the snake_case wire keys for JSON endpoints — mirroring what's already done for form endpoints — or (b) the generated request types reflect the actual wire keys.

Actual

camelCase types + verbatim passthrough → request body the API rejects. Note the response resource classes already read snake_case (payload["friendly_name"]), so the request and response sides are internally inconsistent.

Workaround

Build the body with snake_case / slash-delimited keys and cast past the camelCase types.

Versions

twilio 5.13.1 and 6.0.2; Node 22. Reproduces on both.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions