ESC
Type to search across all documentation

Authentication

All COALS API requests are authenticated with an API key passed in the HTTP Authorization header.

Getting an API Key

API keys are created and managed from your COALS dashboard. Each key can be given a name and scoped to specific services so you can issue minimal-privilege keys for each application.

Manage API Keys

Authorization Header

Pass your API key as a Bearer token in every request. The header is required on all endpoints — requests without it will receive a 401 response.

Header

Authorization: Bearer YOUR_API_KEY

Example Request

curl -X POST https://coals.ai/api/v1/simcoal/send \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+15550001234",
    "message": "Hello from COALS!"
}'
// Using Guzzle
$response = $client->post('https://coals.ai/api/v1/simcoal/send', [
  'headers' => ['Authorization' => 'Bearer YOUR_API_KEY'],
  'json' => [
    "to" => "+15550001234",
    "message" => "Hello from COALS!"
]
]);
$data = json_decode($response->getBody(), true);
# Using requests
import requests

response = requests.post(
  "https://coals.ai/api/v1/simcoal/send",
  headers={"Authorization": "Bearer YOUR_API_KEY"},
  json={
    "to": "+15550001234",
    "message": "Hello from COALS!"
}
)
data = response.json()
# Using net/http
require "net/http"
require "json"

uri = URI("https://coals.ai/api/v1/simcoal/send")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer YOUR_API_KEY"
req["Content-Type"] = "application/json"
req.body = '{
    "to": "+15550001234",
    "message": "Hello from COALS!"
}'

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)
// Using fetch (Node 18+)
const response = await fetch("https://coals.ai/api/v1/simcoal/send", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "to": "+15550001234",
    "message": "Hello from COALS!"
})
});
const data = await response.json();

Scopes

When creating a key you select which scopes it is granted. A key will be rejected with 403 Forbidden if it attempts to call an endpoint outside its granted scopes.

SimCoal — SMS

simcoal:send Send a single SMS message
simcoal:bulk Send SMS to multiple recipients in one request
simcoal:read Read delivery logs and account stats

ConvertaCoal — Files

convertacoal:convert Submit a file conversion job
convertacoal:read Read conversion logs and download converted files

GraphiCoal — Images

graphicoal:generate Generate a new image from a text prompt
graphicoal:edit Edit or inpaint an existing image
graphicoal:analyze Analyze or describe an image
graphicoal:convert Convert a raster image to SVG
graphicoal:read Read generation history and gallery
graphicoal:delete Delete images from your gallery

MagiCoal — Video

magicoal:generate Submit image-to-video or text-to-video generation jobs
magicoal:read Poll job status and read video history

Invalid or Missing Key

When a key is missing, malformed, revoked, or does not exist, the API returns 401 Unauthorized.

Response — 401

{
  "success": false,
  "error": {
    "code":    "UNAUTHORIZED",
    "message": "Invalid or missing API key."
  }
}

Rate limit headers on every response

Every API response includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers so you can monitor consumption in real time. See the Rate Limits page for details.