Getting started
Quickstart
Generate social content with an HTTP request. The Marqal API returns JSON and uses standard HTTP status codes.
- 1Create an account
Sign up and open the API Keys section in your dashboard.
- 2Create your key
Create a live API key and save it securely when it is shown.
- 3Send your first request
Send POST /generate to the base URL below with a platform, goal, and topic.
No SDK required
fetch in JavaScript, and the requests library in Python.Your first request
curl https://wjjdnwgkbydxqegfcvty.supabase.co/functions/v1/generate \
-H "Authorization: Bearer $MARQAL_KEY" \
-H "Content-Type: application/json" \
-d '{
"platform": "linkedin",
"topic": "shipping our new content API",
"goal": "Build awareness",
"variants": 3
}'Security
Authentication
Marqal uses bearer tokens. Send your API key in the Authorization header on every request. Never expose keys in client-side code.
Header format
curl https://wjjdnwgkbydxqegfcvty.supabase.co/functions/v1/generate \
-H "Authorization: Bearer $MARQAL_KEY" \
-H "Content-Type: application/json" \
-d '{"platform":"twitter","goal":"Build awareness","topic":"launch day"}'Unauthorized response
{
"error": "Authentication required."
}Credentials
API Keys
Each Marqal account can have one active live key in the format mq_live_<random>. Create and manage it from your dashboard.
| Field | Type | Description |
|---|---|---|
| Prefix | mq_live_ | Live API traffic for your Marqal account. |
| Length | 56 chars | The mq_live_ prefix followed by a 48-character random value. |
| Scope | Account-wide | One active key per account. |
| Rotation | Instant | Regenerating immediately invalidates the previous key. |
Regenerating a key
From the dashboard, open the API Keys section and click Regenerate key. After confirming, the previous key is revoked immediately and the new secret is shown once. Copy it and update your server-side environment variables right away.
Storing keys
# Set MARQAL_KEY in your server environment to the key from your dashboard.
# usage
curl https://wjjdnwgkbydxqegfcvty.supabase.co/functions/v1/generate \
-H "Authorization: Bearer $MARQAL_KEY" \
-H "Content-Type: application/json" \
-d '{"platform":"linkedin","goal":"Build awareness","topic":"launch day"}'Endpoints
Generate
Generate a social post tailored to a platform, goal, topic, and optional factual evidence.
Body parameters
| Field | Type | Description |
|---|---|---|
| platform | string · required | linkedin · twitter (X) · threads · instagram · tiktok. The alias x is also accepted; matching ignores case and surrounding whitespace. |
| goal | string · required | Non-empty text, up to 200 characters after trimming. Describe the desired outcome, e.g. Build awareness, Drive engagement or Generate leads. This is free text, not an enum. |
| topic | string · required | Non-empty subject text, up to 2,000 characters after trimming. |
| variants | number · optional | Request 1–5 variations; defaults to 3. Finite numeric values are rounded down and clamped to 1–5. Omitted or non-numeric values use 3. |
| evidence | string[] · optional | Factual details supplied by you, not independently verified. Each item must be non-empty after trimming and at most 2,000 characters before trimming. An empty array is allowed. |
Append /generate to the base URL above. Send a JSON object with a maximum encoded body size of 16 KiB (16,384 bytes), including all evidence entries. TikTok output is a text script; all platforms return text.
Request
curl https://wjjdnwgkbydxqegfcvty.supabase.co/functions/v1/generate \
-H "Authorization: Bearer $MARQAL_KEY" \
-H "Content-Type: application/json" \
-d '{
"platform": "linkedin",
"goal": "thought leadership",
"topic": "shipping AI features",
"variants": 1,
"evidence": [
"The release includes automated ticket triage.",
"The feature is available to Pro customers."
]
}'Example response (one variation)
{
"variations": [
{
"id": "v1",
"tone": "strategic insight",
"content": "Your generated post appears here."
}
],
"credits_used": 1
}A successful response contains a variations array with string id, tone and content fields, plus numeric credits_used. The text above is illustrative; tone labels and content can vary. credits_used is usage metadata, not a payment charge during the free beta.
Reference
Rate limits
The public beta is free, with generation request limits shared by each account across API-key and dashboard requests.
| Field | Type | Description |
|---|---|---|
| Concurrent requests | 2 | Maximum in-flight generation requests. |
| Per minute | 8 | Maximum admitted generation requests per UTC clock minute. |
| Per day | 50 | Maximum admitted generation requests per UTC calendar day; resets at 00:00 UTC. |
These limits count admitted requests, not output variations. A request can ask for 1–5 variations. Requests that fail after admission still count toward the minute and daily limits.
Handling 429s
When you exceed the limit, Marqal returns 429 rate_limited with a Retry-After header in seconds. Back off and retry.
# If the response contains Retry-After: 12,
# wait at least 12 seconds before repeating the same POST request.
sleep 12Reference
Errors
Marqal uses conventional HTTP status codes. Some operational errors also include a machine-readable code.
| Field | Type | Description |
|---|---|---|
| 400 | - | The request body or one of its fields is invalid. |
| 401 | - | Authentication is missing or invalid. |
| 405 | - | The HTTP method is not supported. |
| 413 | - | The request body is too large. |
| 429 | rate_limited | Operational rate limit reached. Retry later. |
| 500 | - | An internal server error occurred. |
| 502 | - | Generation failed on the provider or validation path. |
| 503 | limiter_unavailable or no code | A required authentication or rate-limit service is temporarily unavailable. |
Error shape
{
"error": "Missing or invalid field: topic"
}Rate-limit example (HTTP 429)
{
"error": "Generation request not admitted.",
"code": "rate_limited",
"retry_after_seconds": 12
}The retry delay varies by request. A 503 limiter_unavailable response also includes Retry-After and retry_after_seconds. Some 502 generation errors include a failed_variations array; do not assume every error has a code.
Handling errors
Check the HTTP status and the error message. When a code field is present, use it for programmatic handling. For rate limits, respect the Retry-After header before retrying.
