How to Use the Meta Ads API in 2026: The Developer Guide
A practical guide to the Meta Ads API for developers. Learn what changed in v22.0, why the raw API is painful, and how Xylo makes it dramatically simpler with clean REST endpoints.
The Meta Ads API in 2026: What Developers Need to Know
Meta's Marketing API is one of the most powerful advertising interfaces available. It is also one of the most frustrating. If you have ever tried to pull campaign performance data, create an ad set, or manage audiences programmatically, you know the pain: deeply nested JSON responses, inconsistent field naming, required but undocumented parameters, and rate limits that change without warning.
This guide covers the current state of the Meta Ads API (Graph API v22.0), walks through common integration patterns, and shows how Xylo eliminates the complexity so you can ship ad integrations in hours instead of weeks.
What Is the Meta Ads API?
The Meta Ads API (formally the Facebook Marketing API) provides programmatic access to Facebook Ads, Instagram Ads, and Audience Network campaigns. It runs on top of Meta's Graph API infrastructure and exposes endpoints for:
- Campaign management -- create, read, update, and delete campaigns
- Ad set configuration -- targeting, budgets, scheduling, placements
- Ad creative -- images, videos, carousel formats, dynamic creative
- Reporting and insights -- performance metrics, breakdowns, attribution
- Audiences -- custom audiences, lookalike audiences, saved audiences
- Lead forms -- lead gen ad forms and submissions
The API uses OAuth 2.0 for authentication and requires a valid access token scoped to a specific ad account.
Why the Raw Meta API Is Hard
Let us look at a real example. To fetch campaign performance data from Meta, you need to construct a request like this:
curl -G "https://graph.facebook.com/v22.0/act_123456789/campaigns" \
-d "fields=id,name,status,objective,daily_budget,lifetime_budget,bid_strategy,start_time,stop_time,insights.date_preset(last_30d){impressions,clicks,spend,cpc,cpm,ctr,actions,cost_per_action_type}" \
-d "access_token=EAABsbCS1..."
The response looks something like this (abbreviated):
{
"data": [
{
"id": "120210123456789",
"name": "Summer Sale 2026",
"status": "ACTIVE",
"objective": "OUTCOME_SALES",
"daily_budget": "5000",
"insights": {
"data": [
{
"impressions": "142893",
"clicks": "3847",
"spend": "487.23",
"cpc": "0.126639",
"cpm": "3.409876",
"ctr": "2.692518",
"actions": [
{
"action_type": "link_click",
"value": "3102"
},
{
"action_type": "purchase",
"value": "87"
},
{
"action_type": "add_to_cart",
"value": "234"
}
],
"cost_per_action_type": [
{
"action_type": "purchase",
"value": "5.600345"
}
],
"date_start": "2026-03-01",
"date_stop": "2026-03-30"
}
]
}
}
],
"paging": {
"cursors": {
"before": "QVFIUk...",
"after": "QVFIUm..."
}
}
}
There are several problems here:
- Budgets are strings, not numbers.
daily_budget: "5000"is in cents, represented as a string. You have to parse and divide by 100. - Actions are arrays, not objects. To find purchase count, you have to loop through the
actionsarray and match onaction_type. Same for costs. - Nested insights require special syntax. The
insights.date_preset(last_30d){fields}syntax is non-standard and poorly documented. - Pagination uses cursor-based paging. You need to follow
paging.cursors.afterto get subsequent pages. - Rate limits are opaque. Meta uses a "Business Use Case Rate Limit" system that varies by endpoint and app tier.
The Xylo Alternative
Here is the same request through Xylo:
curl "https://api.xyloapi.dev/v1/campaigns?date_preset=last_30d" \
-H "x-api-key: xylo_live_abc123" \
-H "x-ad-account: act_123456789"
And the response:
{
"data": [
{
"id": "120210123456789",
"name": "Summer Sale 2026",
"status": "active",
"objective": "sales",
"daily_budget": 50.00,
"lifetime_budget": null,
"bid_strategy": "lowest_cost",
"start_date": "2026-06-01",
"end_date": null,
"insights": {
"impressions": 142893,
"clicks": 3847,
"spend": 487.23,
"cpc": 0.13,
"cpm": 3.41,
"ctr": 2.69,
"conversions": 87,
"cost_per_conversion": 5.60
}
}
],
"meta": {
"cached": false,
"meta_api_version": "v22.0"
},
"paging": {
"has_next": true,
"cursor": "eyJvZmZzZXQiOjI1fQ=="
}
}
The differences are significant:
| Aspect | Raw Meta API | Xylo API |
|---|---|---|
| Budget format | String in cents ("5000") |
Number in dollars (50.00) |
| Metrics | Nested arrays with action_type matching | Flat object with clear keys |
| Status values | SCREAMING_CASE ("ACTIVE") |
lowercase ("active") |
| Objective names | Internal codes ("OUTCOME_SALES") |
Readable names ("sales") |
| Pagination | Opaque cursor objects | Simple has_next + cursor string |
| Authentication | OAuth token management | Single API key |
Common Integration Patterns
Pulling Daily Performance Reports
Most ad integrations need to pull daily performance data into a reporting dashboard or data warehouse. With Xylo, this is straightforward:
const response = await fetch(
"https://api.xyloapi.dev/v1/campaigns?date_preset=last_7d",
{
headers: {
"x-api-key": process.env.XYLO_API_KEY,
"x-ad-account": "act_123456789",
},
}
);
const { data: campaigns } = await response.json();
for (const campaign of campaigns) {
console.log(`${campaign.name}: $${campaign.insights.spend} spent, ${campaign.insights.conversions} conversions`);
}
Creating a Campaign
Creating campaigns through the raw Meta API requires multiple sequential calls (campaign, then ad set, then creative, then ad). Xylo simplifies the individual steps:
const response = await fetch("https://api.xyloapi.dev/v1/campaigns", {
method: "POST",
headers: {
"x-api-key": process.env.XYLO_API_KEY,
"x-ad-account": "act_123456789",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Q2 Prospecting",
objective: "conversions",
status: "paused",
daily_budget: 100.00,
bid_strategy: "lowest_cost",
}),
});
const { data: campaign } = await response.json();
// campaign.id is now available for creating ad sets
Managing Audiences
Custom audience management is one of the most complex parts of the Meta API. Xylo normalizes the interface:
// List all custom audiences
const audiences = await fetch(
"https://api.xyloapi.dev/v1/audiences",
{ headers: { "x-api-key": key, "x-ad-account": account } }
);
// Create a lookalike audience
const lookalike = await fetch(
"https://api.xyloapi.dev/v1/audiences",
{
method: "POST",
headers: {
"x-api-key": key,
"x-ad-account": account,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Lookalike - Top Customers",
type: "lookalike",
source_audience_id: "23851234567890",
country: "US",
ratio: 0.01,
}),
}
);
Rate Limits and Caching
Meta's rate limiting system is notoriously difficult to work with. The limits vary by endpoint, by app development tier, and by the specific business use case. Xylo handles this in two ways:
- Automatic retry with backoff. When Xylo hits a rate limit, it retries with exponential backoff (up to 3 attempts) before returning an error.
- Response caching. Read endpoints are cached with configurable TTLs. Campaign lists cache for 5 minutes, insights cache for 15 minutes, and targeting options cache for 1 hour. This reduces your effective API call volume significantly.
Authentication Simplified
The Meta API requires OAuth 2.0 tokens that expire and need refreshing. Managing token lifecycle -- initial authorization, storage, refresh, and revocation -- adds significant complexity.
With Xylo, you connect your Meta account once through the dashboard. Xylo securely stores and manages your Meta tokens (encrypted with AES-256-GCM). Your application only needs a single Xylo API key, which never expires until you rotate it.
Getting Started
- Sign up at xyloapi.dev and create an organization.
- Connect your Meta ad account through the dashboard. This triggers a standard Meta OAuth flow.
- Generate an API key from the dashboard.
- Start making requests to
https://api.xyloapi.dev/v1/.
Check the full API documentation for endpoint details, or read about building AI agents for ads to see how Xylo works with MCP-compatible AI tools.
Summary
The Meta Ads API is powerful but complex. The raw Graph API forces you to deal with string-encoded numbers, deeply nested action arrays, opaque pagination, and fragile OAuth token management. Xylo wraps all of this behind clean REST endpoints with normalized responses, automatic retry logic, and built-in caching. If you are building an ad integration, a reporting dashboard, or an AI agent that manages campaigns, Xylo lets you skip the painful parts and focus on your product.
Ready to simplify your ads API integration?
Get started with Xylo in minutes. One API key for every ad platform.