Developer platform
API documentation
Use scoped API keys to send messages, manage contacts and templates, run campaigns, and receive signed events. Every request is isolated to the workspace that owns the key.
Authentication
Send Authorization: Bearer sk_live_xxx. Keys are hashed and can be revoked immediately.
Consistent errors
All API routes return a stable success/error envelope and appropriate HTTP status codes.
Webhooks
Verify X-Webhook-Signature before processing an event.
Send a text message
POST https://messageship.vercel.app/api/v1/messages/send · scope messages:write
curl -X POST https://messageship.vercel.app/api/v1/messages/send \
-H "Authorization: Bearer sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{"whatsappAccountId":"acct_123","to":"15550102000","type":"text","text":{"body":"Hello from MessageShip"}}'import { Whatsapp } from "@messageship/sdk";
const whatsapp = new Whatsapp("sk_live_xxx");
await whatsapp.messages.sendText({
whatsappAccountId: "acct_123",
to: "15550102000",
text: "Hello from MessageShip",
});const response = await fetch("https://messageship.vercel.app/api/v1/messages/send", {
method: "POST",
headers: { Authorization: "Bearer sk_live_xxx", "Content-Type": "application/json" },
body: JSON.stringify({ whatsappAccountId: "acct_123", to: "15550102000", type: "text", text: { body: "Hello" } }),
});import requests
response = requests.post(
"https://messageship.vercel.app/api/v1/messages/send",
headers={"Authorization": "Bearer sk_live_xxx"},
json={"whatsappAccountId": "acct_123", "to": "15550102000", "type": "text", "text": {"body": "Hello"}},
)
response.raise_for_status()var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "sk_live_xxx");
var content = new StringContent("{\"whatsappAccountId\":\"acct_123\",\"to\":\"15550102000\",\"type\":\"text\",\"text\":{\"body\":\"Hello\"}}", System.Text.Encoding.UTF8, "application/json");
await client.PostAsync("https://messageship.vercel.app/api/v1/messages/send", content);<?php
$curl = curl_init("https://messageship.vercel.app/api/v1/messages/send");
curl_setopt_array($curl, [CURLOPT_POST => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer sk_live_xxx", "Content-Type: application/json"], CURLOPT_POSTFIELDS => json_encode(["whatsappAccountId" => "acct_123", "to" => "15550102000", "type" => "text", "text" => ["body" => "Hello"]])]);
curl_exec($curl);Endpoints
POST /messages/sendmessages:writeGET /messagesmessages:readGET /conversationsmessages:readGET /contactscontacts:readPOST /templatestemplates:writePOST /campaignscampaigns:writePOST /webhookswebhooks:writeMessaging rules
Free-form messages are accepted only while the customer-service window is open. Outside that window, use an approved template.
Message status changes come from Meta webhooks. MessageShip does not invent delivery states.
Media inputs must use an uploaded media ID or an HTTPS URL. File validation belongs in the media service boundary.
Response format
{
"success": true,
"data": { "messageId": "wamid_..." }
}Errors use { success: false, error: { code, message } }. Rate limits return HTTP 429.