This API allows authorized systems to manage marketing campaigns, customer groups, client assets and performance metrics across one or multiple stores belonging to the same customer group.
All API requests must include a valid X-API-KEY header. This key identifies the customer group and defines the maximum access scope.
X-API-KEY: your-api-key
Optionally, requests can include an X-BEACON-KEY header to restrict access to a specific store (customer) within the group.
X-BEACON-KEY: external-beacon-uuid
The API automatically scopes data based on the provided headers:
If no beacon key is provided, data is aggregated at group level. All authorization checks are enforced server-side.
GET /api/campaigns
Returns the list of campaigns accessible within the current scope (group-level or store-level depending on headers).
curl -X GET https://api.extranet.lagriffe.io/api/campaigns \ -H "X-API-KEY: your-api-key" \ -H "Accept: application/json"
Response example:
{
"scope": "group",
"campaigns": [
{
"id": 36,
"type": "sea",
"label": "Campagne Meta Juin",
"description": null,
"status": "request",
"external_ref": "1209988776655",
"company": {
"id": 123,
"name": "Store Paris"
},
"channels": ["meta", "google"],
"period": {
"type": "fixed",
"start": "2026-07-01",
"end": "2026-07-31"
},
"budget": {
"total": 2500,
"per_day": 80.65,
"currency": "EUR"
}
}
]
}
---
GET /api/campaigns/{id}
Returns detailed information for a single campaign, including:
Access is restricted by the same scoping rules (customer group and optional beacon key).
---GET /api/campaigns/{id}/metrics
Returns performance metrics for a campaign, aggregated per channel and over time (impressions, reach, clicks, spend, etc.). The response also includes demographic breakdowns by age range and gender when this data has been synchronized from Meta.
curl -X GET https://api.extranet.lagriffe.io/api/campaigns/{id}/metrics \
-H "X-API-KEY: your-api-key" \
-H "Accept: application/json"
Response example:
{
"success": true,
"campaign_id": 36,
"metrics": [
{
"channel": "facebook",
"label": "Meta Ads",
"currency": "EUR",
"periods": [
{
"start": "2026-05-18",
"end": "2026-05-18",
"impressions": 1200,
"reach": 980,
"clicks": 42,
"budget_spent": 38.50,
"notes": null
}
]
}
],
"demographics": [
{
"channel": "facebook",
"periods": [
{
"start": "2026-05-18",
"age_range": "25-34",
"gender": "female",
"impressions": 420,
"reach": 360,
"clicks": 18,
"spend": 14.20,
"results": null
}
]
}
]
}
GET /api/customer-groups
Returns the list of customer groups associated with the API key. In most cases, a single customer group is returned.
POST /api/campaigns
Creates a new marketing campaign for a specific store and automatically generates an internal project with the same type.
SEA payload (JSON or multipart):
{
"type": "sea",
"label": "Campagne Meta Juin",
"company_id": 123,
"channels": ["meta", "google"],
"period_type": "fixed",
"start_date": "2026-07-01",
"end_date": "2026-07-31",
"budget_total": 2500,
"budget_per_day": 80.65,
"currency": "EUR",
"external_ref": "1209988776655"
}
Other campaign payload:
{
"type": "mail",
"label": "Newsletter juillet",
"company_id": 123,
"description": "Objet : newsletter juillet\nCible : clients actifs\nContenu : ..."
}
The company_id identifies the store within the customer group. The legacy external_beacon_key field is also accepted when company_id is not provided. Accepted types are sea, mail, sms and design. For non-SEA campaigns, incoming email, e-mail and newsletter types are normalized to mail.
Client assets (images, briefs, documents) can be uploaded at creation time
using a multipart/form-data request with a files[] field.
curl -X POST https://api.extranet.lagriffe.io/api/campaigns \ -H "X-API-KEY: your-api-key" \ -H "Accept: application/json" \ -F "type=sea" \ -F "company_id=123" \ -F "label=Campagne Meta Juin" \ -F "channels[]=meta" \ -F "channels[]=google" \ -F "period_type=fixed" \ -F "start_date=2026-07-01" \ -F "end_date=2026-07-31" \ -F "budget_total=2500" \ -F "budget_per_day=80.65" \ -F "currency=EUR" \ -F "external_ref=1209988776655" \ -F "files[]=@brief.pdf" \ -F "files[]=@banner.jpg"
All successful responses are returned as JSON and follow a consistent structure.
{
"success": true,
"data": { }
}
In case of an error, the API returns an appropriate HTTP status code along with a JSON error message.
{
"message": "Unauthorized"
}