# Content API Quickstart

Create your first content template and send it using the Content API. Follow the steps to create your own content template and send it to your customers on WhatsApp.

1. [Create a content template](#create-a-content-template).
2. Optional: [Review content templates](#review-content-templates-optional).
3. Optional: [Submit content templates for approval to WhatsApp](#submit-a-content-template-for-whatsapp-approval-optional).
4. Optional: [Fetch an approval status](#fetch-an-approval-status-optional).
5. [Send a message on WhatsApp](#send-a-message-on-whatsapp).

For other requests, see [Content API resources](/docs/content/content-api-resources).

## Prerequisites

Before you send content templates created using the Content API, you must have at least one registered sender. A sender can be one of the following:

* [Phone number](/docs/numbers-and-senders/phone-number-senders)
* [WhatsApp sender](/docs/whatsapp#get-started-with-whatsapp)
* [Facebook Messenger sender](/docs/messaging/channels/facebook-messenger)

### Configure your sender

To send messages across different channels, configure the appropriate sender as follows:

* **RCS**: Request an RCS sender. For more information, see [RCS Onboarding Guide](/docs/rcs/onboarding#setup-and-configuration).
* **SMS or MMS**: Use a [phone number](/docs/numbers-and-senders/phone-number-senders). You can port a number or purchase one from the Twilio Console.
* **WhatsApp**: Use your Twilio phone number or your own number to [register a WhatsApp sender](/docs/whatsapp#whatsapp-sender-registration).
* **Facebook Messenger**: [Connect your Facebook page](/docs/messaging/channels/facebook-messenger#set-up-messaging-with-facebook-messenger) to create a Facebook Messenger sender.

## Create a content template

Create a `twilio/quick-reply` template so recipients can tap, rather than type, to respond to messages on WhatsApp and Facebook Messenger.

If you create a `twilio/text` template, recipients can send quick replies using the pre-configured messages you created. If the recipient's channel doesn't support quick replies, Twilio automatically defaults to a text message. This lets you send the same content across multiple messaging channels.

You can include placeholders (for example, `{{1}}`) in the message body. The placeholder values are updated dynamically when you send the message. If you omit a placeholder value at send time, Twilio uses the default value specified in `variables`.

See the [content types overview](/docs/content/content-types-overview) to learn more about additional content types.

> \[!NOTE]
>
> If you plan to submit your content template for WhatsApp approval, use self-evident default variable values. These values are used as sample values during the approval process.

Replace the `$TWILIO_ACCOUNT_SID` with your Twilio Account SID and `$TWILIO_AUTH_TOKEN` with your Twilio Auth Token for the following examples.

Create your first content template

```bash
curl -X POST 'https://content.twilio.com/v1/Content' \
-H 'Content-Type: application/json' \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN \
-d '{
    "friendly_name": "owl_air_qr",
    "language": "en",
    "variables": {"1":"Owl Air Customer"},
    "types": {
        "twilio/quick-reply": {
                    "body": "Hi, {{1}} 👋 \nThanks for contacting Owl Air Support. How can I help?",
                    "actions": [
                        {
                            "title": "Check flight status",
                            "id": "flightid1"
                        },
                        {
                            "title": "Check gate number",
                            "id": "gateid1"
                        },
                        {
                            "title": "Speak with an agent",
                            "id": "agentid1"
                        }
                    ]
                },
        "twilio/text": {
            "body": "Hi, {{1}}. \n Thanks for contacting Owl Air Support. How can I help?."
        }
    }
}'
```

```json
{
  "account_sid": "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "date_created": "2022-08-29T10:43:20Z",
  "date_updated": "2022-08-29T10:43:20Z",
  "friendly_name": "owl_air_qr",
  "language": "en",
  "links": {
    "approval_create": "https://content.twilio.com/v1/Content/HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/ApprovalRequests/whatsapp",
    "approval_fetch": "https://content.twilio.com/v1/Content/HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/ApprovalRequests"
  },
  "sid": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "types": {
    "twilio/text": {
      "body": "Hi, {{ 1 }}. \n Thanks for contacting Owl Air Support. How can I help?."
    },
    "twilio/quick-reply": {
      "body": "Hi, {{ 1 }}. \n Thanks for contacting Owl Air Support. How can I help?",
      "actions": [
        {
          "id": "flightid1",
          "title": "Check flight status"
        },
        {
          "id": "gateid1",
          "title": "Check gate number"
        },
        {
          "id": "agentid1",
          "title": "Speak with an agent"
        }
      ]
    }
  },
  "url": "https://content.twilio.com/v1/Content/HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "variables": {
    "1": "Owl Air Customer"
  }
}
```

After you create your first content template, make a note of the `sid` value (for example, `HXXXXXXXXXXXXXXXXXXX`) in the response. You'll use the `sid` for other requests.

> \[!NOTE]
>
> The Content API supports an unlimited number of content templates. However, WhatsApp limits each business to 6,000 approved content templates per WhatsApp Business Account (WABA).

## Review content templates (optional)

Make a `GET` request to review all content templates. To review a specific content template, include `{ContentSid}` in the request URL path.

Review Content API templates

```js
// Download the helper library from https://www.twilio.com/docs/node/install
const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";

// Find your Account SID and Auth Token at twilio.com/console
// and set the environment variables. See http://twil.io/secure
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = twilio(accountSid, authToken);

async function fetchContent() {
  const content = await client.content.v1.contents("HXXXXXXX").fetch();

  console.log(content.dateCreated);
}

fetchContent();
```

```python
# Download the helper library from https://www.twilio.com/docs/python/install
import os
from twilio.rest import Client

# Find your Account SID and Auth Token at twilio.com/console
# and set the environment variables. See http://twil.io/secure
account_sid = os.environ["TWILIO_ACCOUNT_SID"]
auth_token = os.environ["TWILIO_AUTH_TOKEN"]
client = Client(account_sid, auth_token)

content = client.content.v1.contents("HXXXXXXX").fetch()

print(content.date_created)
```

```csharp
// Install the C# / .NET helper library from twilio.com/docs/csharp/install

using System;
using Twilio;
using Twilio.Rest.Content.V1;
using System.Threading.Tasks;

class Program {
    public static async Task Main(string[] args) {
        // Find your Account SID and Auth Token at twilio.com/console
        // and set the environment variables. See http://twil.io/secure
        string accountSid = Environment.GetEnvironmentVariable("TWILIO_ACCOUNT_SID");
        string authToken = Environment.GetEnvironmentVariable("TWILIO_AUTH_TOKEN");

        TwilioClient.Init(accountSid, authToken);

        var content = await ContentResource.FetchAsync(pathSid: "HXXXXXXX");

        Console.WriteLine(content.DateCreated);
    }
}
```

```java
// Install the Java helper library from twilio.com/docs/java/install

import com.twilio.Twilio;
import com.twilio.rest.content.v1.Content;

public class Example {
    // Find your Account SID and Auth Token at twilio.com/console
    // and set the environment variables. See http://twil.io/secure
    public static final String ACCOUNT_SID = System.getenv("TWILIO_ACCOUNT_SID");
    public static final String AUTH_TOKEN = System.getenv("TWILIO_AUTH_TOKEN");

    public static void main(String[] args) {
        Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
        Content content = Content.fetcher("HXXXXXXX").fetch();

        System.out.println(content.getDateCreated());
    }
}
```

```go
// Download the helper library from https://www.twilio.com/docs/go/install
package main

import (
	"fmt"
	"github.com/twilio/twilio-go"
	"os"
)

func main() {
	// Find your Account SID and Auth Token at twilio.com/console
	// and set the environment variables. See http://twil.io/secure
	// Make sure TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN exists in your environment
	client := twilio.NewRestClient()

	resp, err := client.ContentV1.FetchContent("HXXXXXXX")
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	} else {
		if resp.DateCreated != nil {
			fmt.Println(*resp.DateCreated)
		} else {
			fmt.Println(resp.DateCreated)
		}
	}
}
```

```php
<?php

// Update the path below to your autoload.php,
// see https://getcomposer.org/doc/01-basic-usage.md
require_once "/path/to/vendor/autoload.php";

use Twilio\Rest\Client;

// Find your Account SID and Auth Token at twilio.com/console
// and set the environment variables. See http://twil.io/secure
$sid = getenv("TWILIO_ACCOUNT_SID");
$token = getenv("TWILIO_AUTH_TOKEN");
$twilio = new Client($sid, $token);

$content = $twilio->content->v1->contents("HXXXXXXX")->fetch();

print $content->dateCreated?->format("r");
```

```ruby
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'twilio-ruby'

# Find your Account SID and Auth Token at twilio.com/console
# and set the environment variables. See http://twil.io/secure
account_sid = ENV['TWILIO_ACCOUNT_SID']
auth_token = ENV['TWILIO_AUTH_TOKEN']
@client = Twilio::REST::Client.new(account_sid, auth_token)

content = @client
          .content
          .v1
          .contents('HXXXXXXX')
          .fetch

puts content.date_created
```

```bash
# Install the twilio-cli from https://twil.io/cli

twilio api:content:v1:content:fetch \
   --sid HXXXXXXX
```

```bash
curl -X GET "https://content.twilio.com/v1/Content/HXXXXXXX" \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN
```

```json
{
  "sid": "HXXXXXXX",
  "account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "friendly_name": "Some content",
  "language": "en",
  "variables": {
    "name": "foo"
  },
  "types": {
    "twilio/text": {
      "body": "Foo Bar Co is located at 39.7392, 104.9903"
    },
    "twilio/location": {
      "longitude": 104.9903,
      "latitude": 39.7392,
      "label": "Foo Bar Co"
    }
  },
  "url": "https://content.twilio.com/v1/Content/HXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "date_created": "2015-07-30T19:00:00Z",
  "date_updated": "2015-07-30T19:00:00Z",
  "links": {
    "approval_create": "https://content.twilio.com/v1/Content/HXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/ApprovalRequests/whatsapp",
    "approval_fetch": "https://content.twilio.com/v1/Content/HXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/ApprovalRequests"
  }
}
```

## Submit a content template for WhatsApp approval (optional)

To start business-initiated conversations on WhatsApp, you must [submit your message template for approval](#submit-a-content-template-for-whatsapp-approval-optional). The approval process typically takes between 5 minutes and 24 hours.

WhatsApp has strict template approval criteria. Learn more about [WhatsApp approval requirements](/docs/content/content-types-overview#whatsapp-approval-requirements) and [best practices](/docs/whatsapp/tutorial/send-whatsapp-notification-messages-templates#whatsapp-message-templates-overview).

Submit a template for WhatsApp approval

```bash
curl -X POST 'https://content.twilio.com/v1/Content/HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/ApprovalRequests/whatsapp' \
-H 'Content-Type: application/json' \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN \
-d '{
  "name": "flight_replies",
  "category": "UTILITY"
}'
```

```json
{
  "category": "TRANSPORTATION_UPDATE",
  "status": "received",
  "rejection_reason": "",
  "name": "flight_replies",
  "content_type": "twilio/quick-reply"
}
```

## Fetch an approval status (optional)

Fetching an approval status returns the current state of the WhatsApp template approval submission. The following statuses are possible:

* `Received`: The request has successfully been submitted to Twilio. Generally Twilio submits these immediately to WhatsApp.
* `Pending`: WhatsApp has received the submission and is processing the request.
* `Approved`: WhatsApp has approved the template and it's now available for use.
* `Rejected`: WhatsApp has rejected the request. You can find the rejection reason in the `rejection_reason` field. Learn more about [the approval process and best practices](/docs/whatsapp/tutorial/message-template-approvals-statuses).

> \[!WARNING]
>
> To support WhatsApp flows, Twilio returns a flow object in the approval request response.

Check a template's approval status

```bash
curl -X GET 'https://content.twilio.com/v1/Content/HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/ApprovalRequests' \
-H 'Content-Type: application/json' \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN
```

```json
{
    "url": "https://content.twilio.com/v1/Content/HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/ApprovalRequests",
    "whatsapp": {
        "category": "TRANSPORTATION_UPDATE",
        "status": "pending",
        "name": "flight_replies",
        "type": "whatsapp",
        "content_type": "twilio/quick-reply",
        "rejection_reason": ""
    },
    "account_sid": "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "sid": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
```

## Send a message on WhatsApp

You can send messages without WhatsApp approval for up to 24 hours by responding to an inbound message from the end user.

After you receive an inbound message (for example, "hi") from the user, send the `twilio/quick-reply` template you created. Include the following parameters:

| Field              | Description                                                                                                                                                                                                                     |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `From`             | The identifier of the sender. Use the folllowing format: <ul><li>Phone numbers: [E.164 format](/docs/glossary/what-e164)</li><li>WhatsApp: `whatsapp:E.164`</li><li>Facebook Messenger: `messenger:{messenger_id}`</li></ul>    |
| `To`               | The identifier of the recipient. Use the folllowing format: <ul><li>Phone numbers: [E.164 format](/docs/glossary/what-e164)</li><li>WhatsApp: `whatsapp:E.164`</li><li>Facebook Messenger: `messenger:{messenger_id}`</li></ul> |
| `ContentSid`       | The Content SID (for example, `HXXXXXXXXXXXXXXXX`).                                                                                                                                                                             |
| `ContentVariables` | The values you want to substitute into your placeholder variables.                                                                                                                                                              |

Send a content template created using Content API

```js
// Download the helper library from https://www.twilio.com/docs/node/install
const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";

// Find your Account SID and Auth Token at twilio.com/console
// and set the environment variables. See http://twil.io/secure
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = twilio(accountSid, authToken);

async function createMessage() {
  const message = await client.messages.create({
    contentSid: "HXXXXXXX",
    contentVariables: JSON.stringify({ 1: "Name" }),
    from: "whatsapp:+18551234567",
    to: "whatsapp:+18551234567",
  });

  console.log(message.body);
}

createMessage();
```

```python
# Download the helper library from https://www.twilio.com/docs/python/install
import os
from twilio.rest import Client
import json

# Find your Account SID and Auth Token at twilio.com/console
# and set the environment variables. See http://twil.io/secure
account_sid = os.environ["TWILIO_ACCOUNT_SID"]
auth_token = os.environ["TWILIO_AUTH_TOKEN"]
client = Client(account_sid, auth_token)

message = client.messages.create(
    content_sid="HXXXXXXX",
    to="whatsapp:+18551234567",
    from_="whatsapp:+18551234567",
    content_variables=json.dumps({"1": "Name"}),
)

print(message.body)
```

```csharp
// Install the C# / .NET helper library from twilio.com/docs/csharp/install

using System;
using Twilio;
using Twilio.Rest.Api.V2010.Account;
using System.Threading.Tasks;
using System.Collections.Generic;
using Newtonsoft.Json;

class Program {
    public static async Task Main(string[] args) {
        // Find your Account SID and Auth Token at twilio.com/console
        // and set the environment variables. See http://twil.io/secure
        string accountSid = Environment.GetEnvironmentVariable("TWILIO_ACCOUNT_SID");
        string authToken = Environment.GetEnvironmentVariable("TWILIO_AUTH_TOKEN");

        TwilioClient.Init(accountSid, authToken);

        var message = await MessageResource.CreateAsync(
            contentSid: "HXXXXXXX",
            to: new Twilio.Types.PhoneNumber("whatsapp:+18551234567"),
            from: new Twilio.Types.PhoneNumber("whatsapp:+18551234567"),
            contentVariables: JsonConvert.SerializeObject(
                new Dictionary<string, Object>() { { "1", "Name" } }, Formatting.Indented));

        Console.WriteLine(message.Body);
    }
}
```

```java
// Install the Java helper library from twilio.com/docs/java/install

import com.twilio.type.PhoneNumber;
import java.util.HashMap;
import java.util.Map;
import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Message;
import org.json.JSONObject;

public class Example {
    // Find your Account SID and Auth Token at twilio.com/console
    // and set the environment variables. See http://twil.io/secure
    public static final String ACCOUNT_SID = System.getenv("TWILIO_ACCOUNT_SID");
    public static final String AUTH_TOKEN = System.getenv("TWILIO_AUTH_TOKEN");

    public static void main(String[] args) {
        Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
        Message message = Message
                              .creator(new com.twilio.type.PhoneNumber("whatsapp:+18551234567"),
                                  new com.twilio.type.PhoneNumber("whatsapp:+18551234567"),
                                  "HXXXXXXX")
                              .setContentVariables(new JSONObject(new HashMap<String, Object>() {
                                  {
                                      put("1", "Name");
                                  }
                              }).toString())
                              .create();

        System.out.println(message.getBody());
    }
}
```

```go
// Download the helper library from https://www.twilio.com/docs/go/install
package main

import (
	"encoding/json"
	"fmt"
	"github.com/twilio/twilio-go"
	api "github.com/twilio/twilio-go/rest/api/v2010"
	"os"
)

func main() {
	// Find your Account SID and Auth Token at twilio.com/console
	// and set the environment variables. See http://twil.io/secure
	// Make sure TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN exists in your environment
	client := twilio.NewRestClient()

	ContentVariables, ContentVariablesError := json.Marshal(map[string]interface{}{
		"1": "Name",
	})

	if ContentVariablesError != nil {
		fmt.Println(ContentVariablesError)
		os.Exit(1)
	}

	params := &api.CreateMessageParams{}
	params.SetContentSid("HXXXXXXX")
	params.SetTo("whatsapp:+18551234567")
	params.SetFrom("whatsapp:+18551234567")
	params.SetContentVariables(string(ContentVariables))

	resp, err := client.Api.CreateMessage(params)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	} else {
		if resp.Body != nil {
			fmt.Println(*resp.Body)
		} else {
			fmt.Println(resp.Body)
		}
	}
}
```

```php
<?php

// Update the path below to your autoload.php,
// see https://getcomposer.org/doc/01-basic-usage.md
require_once "/path/to/vendor/autoload.php";

use Twilio\Rest\Client;

// Find your Account SID and Auth Token at twilio.com/console
// and set the environment variables. See http://twil.io/secure
$sid = getenv("TWILIO_ACCOUNT_SID");
$token = getenv("TWILIO_AUTH_TOKEN");
$twilio = new Client($sid, $token);

$message = $twilio->messages->create(
    "whatsapp:+18551234567", // To
    [
        "contentSid" => "HXXXXXXX",
        "from" => "whatsapp:+18551234567",
        "contentVariables" => json_encode([
            "1" => "Name",
        ]),
    ]
);

print $message->body;
```

```ruby
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'twilio-ruby'

# Find your Account SID and Auth Token at twilio.com/console
# and set the environment variables. See http://twil.io/secure
account_sid = ENV['TWILIO_ACCOUNT_SID']
auth_token = ENV['TWILIO_AUTH_TOKEN']
@client = Twilio::REST::Client.new(account_sid, auth_token)

message = @client
          .api
          .v2010
          .messages
          .create(
            content_sid: 'HXXXXXXX',
            to: 'whatsapp:+18551234567',
            from: 'whatsapp:+18551234567',
            content_variables: {
                '1' => 'Name'
              }.to_json
          )

puts message.body
```

```bash
# Install the twilio-cli from https://twil.io/cli

twilio api:core:messages:create \
   --content-sid HXXXXXXX \
   --to whatsapp:+18551234567 \
   --from whatsapp:+18551234567 \
   --content-variables {\"1\":\"Name\"}
```

```bash
CONTENT_VARIABLES_OBJ=$(cat << EOF
{
  "1": "Name"
}
EOF
)
curl -X POST "https://api.twilio.com/2010-04-01/Accounts/$TWILIO_ACCOUNT_SID/Messages.json" \
--data-urlencode "ContentSid=HXXXXXXX" \
--data-urlencode "To=whatsapp:+18551234567" \
--data-urlencode "From=whatsapp:+18551234567" \
--data-urlencode "ContentVariables=$CONTENT_VARIABLES_OBJ" \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN
```

```json
{
  "account_sid": "ACXXXXXXX",
  "api_version": "2010-04-01",
  "body": "Hello! 👍",
  "date_created": "Thu, 24 Aug 2023 05:01:45 +0000",
  "date_sent": "Thu, 24 Aug 2023 05:01:45 +0000",
  "date_updated": "Thu, 24 Aug 2023 05:01:45 +0000",
  "direction": "outbound-api",
  "error_code": null,
  "error_message": null,
  "from": "whatsapp:+18551234567",
  "num_media": "0",
  "num_segments": "1",
  "price": null,
  "price_unit": null,
  "messaging_service_sid": "MGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "sid": "SMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "status": "queued",
  "subresource_uris": {
    "media": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Messages/SMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Media.json"
  },
  "to": "whatsapp:+18551234567",
  "uri": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Messages/SMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.json"
}
```

You receive a response from your WhatsApp sender.

If you change the recipient and sender in the `To` and `From` fields to SMS-capable phone numbers, you'll receive the `twilio/text` content instead.

![Owl Air Support chat offering options to check flight status, gate number, or speak with an agent.](https://docs-resources.prod.twilio.com/0b548e5684c4b8d2d25cf9b53e76e18064d362563dd318a9bd4ca0f43eb6edc8.png)

## What's next

* Learn more about the supported [content types](/docs/content/content-types-overview).
* Review the [Content API resources](/docs/content/content-api-resources).
