One endpoint to create a campaign
The campaign endpoint returns three dialect-aware copy variants, a WhatsApp template draft, and any enabled image or speech deliverables. Use the individual endpoints when your product needs finer control.
6
campaign & speech dialects
4
generation products
1
shared credit balance
Server-side authentication
Create a key from the Developer dashboard when your account has paid access through an active plan or an approved partner entitlement. Send it as a Bearer token from your backend. A key is displayed once, stored by Lahjty only as a one-way hash, and can be revoked immediately.
Authorization: Bearer lhj_live_••••••••••••Never place a key in a URL or source repository. Use a separate key for each environment or integration.
Endpoints
| Method | Path | Purpose | Credits |
|---|---|---|---|
| GET | /api/v1/capabilities | Public values, current costs, and rate limits | — |
| POST | /api/v1/copy-generations | Ad copy, headlines, or dialect conversion | 1–2 |
| POST | /api/v1/image-generations | Durably hosted campaign image | 5 |
| POST | /api/v1/speech-generations | Durably hosted Arabic MP3 | 5 |
| POST | /api/v1/campaigns | Copy + WhatsApp draft + enabled media | 2–12 |
| GET | /api/v1/usage | Balance and recent API usage | — |
| GET | /api/v1/requests/{request_id} | Stored status and result | — |
Complete campaign request
This shape is designed for WhatsApp marketing platforms while remaining provider-neutral. external_id and external_customer_id let you map the result to your own records.
curl https://www.lahjty.com/api/v1/campaigns \
-H "Authorization: Bearer $LAHJTY_API_KEY" \
-H "Idempotency-Key: campaign-1842" \
-H "Content-Type: application/json" \
-d '{
"external_id": "campaign-1842",
"external_customer_id": "merchant-91",
"brief": {
"description": "Weekend offer for a specialty coffee subscription",
"offer": "20% off through Saturday",
"objective": "Drive WhatsApp orders",
"dialect": "saudi",
"platform": "whatsapp",
"tone": "warm",
"audience": "specific",
"specific_audience": "Young professionals in Riyadh",
"keywords": ["نهاية الأسبوع"],
"required_keywords": ["قهوة مختصة"],
"excluded_keywords": ["مجاني"],
"call_to_action": "اطلب الآن"
},
"deliverables": {
"copy": { "type": "ad_copy", "framework": "aida" },
"image": {
"enabled": true,
"type": "product_showcase",
"style": "photorealistic",
"aspect_ratio": "1:1",
"visual_keywords": ["specialty coffee", "Riyadh"],
"excluded_visuals": ["people", "logos"],
"include_text": true,
"overlay_text": "اطلب الآن",
"overlay_text_language": "ar"
},
"speech": {
"enabled": false,
"voice_profile": "confident_announcer",
"delivery": "natural",
"content_type": "marketing"
}
}
}'JavaScript / TypeScript
const response = await fetch(
"https://www.lahjty.com/api/v1/campaigns",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.LAHJTY_API_KEY}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
brief: {
description: "Weekend coffee subscription offer",
dialect: "saudi",
platform: "whatsapp",
required_keywords: ["قهوة مختصة"],
excluded_keywords: ["مجاني"],
},
deliverables: {
copy: { type: "ad_copy", framework: "aida" },
image: {
enabled: true,
type: "offer_announcement",
include_text: true,
overlay_text: "Weekend offer",
overlay_text_language: "en",
},
speech: { enabled: false },
},
}),
},
);
if (!response.ok) {
const problem = await response.json();
throw new Error(`${problem.code}: ${problem.detail}`);
}
const campaign = await response.json();Complete generation controls
The endpoint selects the asset family. Copy type, image type, rendering style, audience, framework, brand context, image text, and voice persona are separate controls so integrations never need to hide important Lahjty behavior inside one prompt.
| Control | Fields | Supported values |
|---|---|---|
| Primary input | description · prompt · text | Copy/campaign brief · image brief · exact speech transcript |
| Copy type | type / deliverables.copy.type | ad_copy · headlines · dialect_conversion |
| Copy framework | framework | none · aida · pas · fab · story |
| Audience | audience · specific_audience · target_audience | 19 segments or free-form detail |
| Language market | dialect · platform · tone | 7 copy dialects · 10 platforms · custom tone |
| Campaign facts | product · offer · objective · call_to_action | Optional bounded factual context |
| Copy keywords | keywords · required_keywords · excluded_keywords | Up to 20 per field with deterministic hard-rule checks |
| Brand context | brand_profile_id | Copy, campaign, and standalone image |
| Image type | type | campaign_visual · product_showcase · lifestyle · offer_announcement · brand_awareness |
| Image style | style | photorealistic · illustration · flat-design · 3d-render · watercolor · minimalist |
| Image layout | aspect_ratio | 1:1 · 2:3 · 3:2 · 3:4 · 4:3 · 4:5 · 5:4 · 9:16 · 16:9 |
| Image text | include_text · overlay_text · overlay_text_language | text-free · auto · ar · en |
| Visual rules | visual_keywords · excluded_visuals | Up to 20 required and 20 excluded concepts |
| Speech | voice_profile · voice · delivery · content_type | 4 Lahjty profiles · provider override · 7 deliveries · marketing/general |
| Deliverables | deliverables.image.enabled · deliverables.speech.enabled | Copy always · optional image · optional speech |
| Partner mapping | external_id · external_customer_id · metadata | Your IDs plus up to 20 metadata strings |
Preferred, required, and excluded keywords
Use keywords for natural preferences, required_keywords for phrases that must appear in every variant, and excluded_keywords for phrases that must never appear. Lahjty validates every variant, retries once when needed, and returns content_rejected instead of non-compliant copy.
Image text and visual controls
Set include_text to false for strict text-free mode. For an overlay, set include_text to true, supply overlay_text, and choose auto, ar, or en. auto preserves the supplied phrase; ar or en translates a mismatched phrase first. Lahjty then places the exact Arabic or English text deterministically over a clean generated base image instead of asking the image model to spell it. visual_keywords request scene concepts and excluded_visuals remove unwanted elements.
// Strict text-free image
{
"prompt": "Premium Saudi coffee campaign",
"type": "product_showcase",
"style": "photorealistic",
"aspect_ratio": "1:1",
"visual_keywords": ["Saudi coffee cup", "coffee beans"],
"excluded_visuals": ["people", "logos"],
"include_text": false
}
// Arabic overlay
{
"prompt": "Premium Saudi coffee campaign",
"type": "offer_announcement",
"include_text": true,
"overlay_text": "قهوتك، بطابعك",
"overlay_text_language": "ar"
}
// English overlay; auto also preserves English input
{
"prompt": "Premium Saudi coffee campaign",
"type": "lifestyle",
"include_text": true,
"overlay_text": "Weekend coffee offer",
"overlay_text_language": "en"
}The returned WhatsApp template is a draft. Your WhatsApp provider remains responsible for Meta template validation and approval.
Shared credits
API requests use the exact same Lahjty balance as the dashboard. Purchased, subscription, coupon, and manually granted admin credits are all usable. A failed provider generation is refunded automatically.
1
dialect conversion
2
copy or headlines
5
image
5
speech
Safe retries and production behavior
- Send a unique Idempotency-Key for each logical POST operation.
- After a network interruption, retry the same body with the same key to replay the stored result.
- Use a new key for a new operation; changing the body under a used key returns 409.
- Honor Retry-After and RateLimit headers after a 429.
- Persist request_id and your external_id in application logs.
Predictable errors
Errors use application/problem+json with a stable code, human-readable detail, and request_id. Keep the request ID in your logs and support tickets.
{
"type": "https://www.lahjty.com/problems/insufficient-credits",
"title": "Insufficient credits",
"status": 402,
"code": "insufficient_credits",
"detail": "This request costs 7 credits; the current balance is 3.",
"request_id": "req_01…"
}Production checklist
- Keep API keys in server-side secrets.
- Allow at least 60 seconds for generation and 120 seconds for complete campaigns.
- Put generated content through human review before a bulk send.
- Monitor GET /usage and alert before the balance is exhausted.
- Revoke old keys immediately after rotation.