NAV Navbar
shell javascript python go

👋 Hello

💬 Code examples appear here. Switch to your preferred language using the tabs above.

Welcome to the OpenMessage API!

The OpenMessage API enables you to drive transactional and conversational messaging from other apps.

🔐 Authentication

⚠️WARNING: This authentication mechanism assumes the API_KEY and API_SECRET are stored securely (not in a web app or a mobile app), if your use case requires this please contact us at hello@openmessage.io

You will first need an Open Message account that you can get at app.openmessage.io, once you have that email hello@openmessage.io to get an API_KEY and API_SECRET that you will use to authenticate.

To authenticate and obtain an Access Token (JWT), make a POST request with the API_KEY and API_SECRET to /auth/token

curl -X POST "https://api.openmessage.io/auth/token" \
  -H 'content-type: application/json' \
  -d '{
        "apiKey": "<API_KEY>",
        "apiSecret": "<API_SECRET>"
      }'
var request = require('request');

var options = {
    url: 'https://api.openmessage.io/auth/token',
    method: 'POST',
    body: {
      apiKey: "<API_KEY>",
      apiSecret: "<API_SECRET>"
    }
};

function callback(error, response, body) {
    if (!error && response.statusCode == 200) {
        console.log(body);
    }
}

request(options, callback);
import requests

data = {
  apiKey: '<API_KEY>',
  apiSecret: '<API_SECRET>'
}

response = requests.post('https://api.openmessage.io/auth/token', data=data)


package main

import (
  "fmt"
  "io/ioutil"
  "log"
  "net/http"
)

func main() {
  client := &http.Client{}
  var data = []byte(`{apiKey: "<API_KEY>", apiSecret: "<API_SECRET>"}`)
  req, err := http.NewRequest("POST", "https://api.openmessage.io/auth/token
", nil)
  if err != nil {
    log.Fatal(err)
  }
  resp, err := client.Do(req)
  if err != nil {
    log.Fatal(err)
  }
  bodyText, err := ioutil.ReadAll(resp.Body)
  if err != nil {
    log.Fatal(err)
  }
  fmt.Printf("%s\n", bodyText)
}

Response Payload: json { "accessToken": "access_token" }

You can use this token in further requests, see Authorization below; access tokens expire after 30 days, so you will need to make the authentication request again to obtain a new access_token.

🔐 Authorization

To authorize a request, pass the Access Token obtained in the Authentication step in the Authorization header, e.g.:

curl "https://api.openmessage.io/"
  -H "Authorization: Bearer <access_token>"
var request = require('request');

var headers = {
    'Authorization': 'Bearer <access_token>'
};

var options = {
    url: 'https://api.openmessage.io/',
    headers: headers
};

function callback(error, response, body) {
    if (!error && response.statusCode == 200) {
        console.log(body);
    }
}

request(options, callback);
import requests

headers = {
    'Authorization': 'Bearer <access_token>',
}

response = requests.get('https://api.openmessage.io/', headers=headers)


package main

import (
  "fmt"
  "io/ioutil"
  "log"
  "net/http"
)

func main() {
  client := &http.Client{}
  req, err := http.NewRequest("GET", "https://api.openmessage.io/
", nil)
  if err != nil {
    log.Fatal(err)
  }
  req.Header.Set("Authorization", "Bearer <access_token>")
  resp, err := client.Do(req)
  if err != nil {
    log.Fatal(err)
  }
  bodyText, err := ioutil.ReadAll(resp.Body)
  if err != nil {
    log.Fatal(err)
  }
  fmt.Printf("%s\n", bodyText)
}

OpenMessage uses API Credentials to allow access to the API. You can register a new OpenMessage API key at app.openmessage.io.

OpenMessage expects the API Access Token to be included in all API requests in a header that looks like this:

Authorization: Bearer <access_token>

📦 Resources

The OM API follows general REST principles by exposing resource collections over HTTP+JSON.

Contacts

Contacts are the recipients of messages and participants in conversations with the organization.

Upload Multiple Contacts to Audience

curl  -H "Authorization: Bearer <access_token>" -XPOST "https://api.openmessage.io/contacts?audience=8" \
-d "{ "first_name": "John","last_name": "Doe","phone": "8105555555","email": "john.doe%40example.com"},{"first_name": "Jane","last_name": "Doe","phone": "8105555555","email": "jane.doe%40example.com"}"
import requests

headers = {
    'Authorization': 'Bearer <access_token>',
}

data = '{ first_name: John,last_name: Doe,phone: 8105555555,email: john.doe@example.com},{first_name: Jane,last_name: Doe,phone: 8105555555,email: jane.doe@example.com}'

response = requests.post('https://api.openmessage.io/contacts?audience=8', headers=headers, data=data)
var request = require('request');

var headers = {
    'Authorization': 'Bearer <access_token>'
};

var dataString = '{ first_name: John,last_name: Doe,phone: 8105555555,email: john.doe%40example.com},{first_name: Jane,last_name: Doe,phone: 8105555555,email: jane.doe%40example.com}';

var options = {
    url: 'https://api.openmessage.io/contacts?audience=8',
    method: 'POST',
    headers: headers,
    body: dataString
};

function callback(error, response, body) {
    if (!error && response.statusCode == 200) {
        console.log(body);
    }
}

request(options, callback);
package main

import (
  "fmt"
  "io/ioutil"
  "log"
  "net/http"
)

func main() {
  client := &http.Client{}
  var data = []byte(`{ first_name: John,last_name: Doe,phone: 8105555555,email: john.doe%40example.com},{first_name: Jane,last_name: Doe,phone: 8105555555,email: jane.doe%40example.com}`)
  req, err := http.NewRequest("POST", "https://api.openmessage.io/contacts?audience=8", data)
  if err != nil {
    log.Fatal(err)
  }
  req.Header.Set("Authorization", "Bearer <access_token>")
  resp, err := client.Do(req)
  if err != nil {
    log.Fatal(err)
  }
  bodyText, err := ioutil.ReadAll(resp.Body)
  if err != nil {
    log.Fatal(err)
  }
  fmt.Printf("%s\n", bodyText)
}

Response Payload:

{
  "data": {}
}

Openmessage allows you to import a list of customers in a batch operation.

POST https://api.openmessage.io/contacts?audience=audience_id

Parameter Type Description
audience_id Integer If specified, the result will only include customers from the designated audience.
payload Array JSON URLEncoded string representing the array of contacts to upload

Messages

Messages represent what is sent over MMS/SMS. There are two types of messages:

  1. Composer template - messages created in the composer use this.
  2. Static media - for pre-rendered media URLs.

All message types support a text field as a caption to the primary media, which appears as a regular SMS text message underneath.

If the text field string value contains a URL, most recent devices will show an image preview of the link instead of plain text. In order for the link preview to work, these conditions must be true:

Send Message

This is the bread and butter for transactional messages, you will be calling this endpoint to send a precreated message to an existing/created/updated customer.

curl -X POST 'https://api.openmessage.io/messages/send' \
     -H 'Content-Type: application/json' \
     -H 'Authorization: Bearer <access_token>' \
     -d '{
        "templateId":99,
        "contactId":3,
        "phone":"+19996667777",
        "context": {
          "myKey": "myValue"
        }
      }'
import requests

headers = {
    'Authorization': 'Bearer <access_token>',
    'Content-Type': 'application/json',
}

data = '{"templateId":99,"contactId":3,"phone":"+19996667777","context":{"myKey":"myValue"}}'

response = requests.post('https://api.openmessage.io/messages/send', headers=headers, data=data)
var request = require('request');

var headers = {
    'Authorization': 'Bearer <access_token>',
    'Content-Type': 'application/json'
};

var dataString = '{"templateId":99,"contactId":3,"phone":"+19996667777","context":{"myKey": "myValue"}}';

var options = {
    url: 'https://api.openmessage.io/messages/send',
    method: 'POST',
    headers: headers,
    body: dataString
};

function callback(error, response, body) {
    if (!error && response.statusCode == 200) {
        console.log(body);
    }
}

request(options, callback);
package main

import (
  "fmt"
  "io/ioutil"
  "log"
  "net/http"
)

func main() {
  client := &http.Client{}
  var data = []byte(`{{"templateId":99,"contactId":3,"phone":"+19996667777","context": {"myKey":"myValue"}}}`)
  req, err := http.NewRequest("POST", "https://api.openmessage.io/messages/send", data)
  if err != nil {
    log.Fatal(err)
  }
  req.Header.Set("Authorization", "Bearer <access_token>")
  req.Header.Set("Content-Type", "application/json")
  resp, err := client.Do(req)
  if err != nil {
    log.Fatal(err)
  }
  bodyText, err := ioutil.ReadAll(resp.Body)
  if err != nil {
    log.Fatal(err)
  }
  fmt.Printf("%s\n", bodyText)
}

Response Payload:

Unique Identifier of the message

1561385857101-0

Send a single message by messageId, customerId and organizationId

POST https:/messages/send

Parameter Description Required
templateId The message Id to send true
contactId The contact to send the message to either contactId or phone
phone A phone number of the contact to send the message to, if the number is not registered a new contact will be created. either contactId or phone
context A custom object with Keys and Values to replace in the message template false

🚫 Errors

The OM API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key is wrong.
403 Forbidden -- The url requested is hidden for administrators only.
404 Not Found -- The specified url could not be found.
405 Method Not Allowed -- Indicates that the specified request HTTP method was received and recognized by the server, but the server has rejected that particular method for the requested resource
406 Not Acceptable -- You requested a format that isn't json.
410 Gone -- Client error response code indicates that access to the target resource is no longer available at the origin server and that this condition is likely to be permanent.
429 Too Many Requests
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.