Adspyre API

API Reference

Full REST API reference for Adspyre. Authenticate with an API key to access all platform features programmatically.

Authentication

All API v1 endpoints require an API key. Generate keys in Settings → API Keys.

Pass the key in one of three ways:

MethodExample
Header (recommended)X-Api-Key: as_live_...
Bearer tokenAuthorization: Bearer as_live_...
Query parameter?api_key=as_live_...

Security: Never expose your API key in client-side code. All requests should be made server-side.


Base URL

https://adspyre.com/api

All v1 endpoints are prefixed with /v1/.


Endpoints

GET /v1/account

Returns current account status: tariff plan, credit balance, and plan expiry date.

Request

GET /api/v1/account
X-Api-Key: as_live_your_key_here

Response

{
  "success": true,
  "message": "OK",
  "tariff": "Pro",
  "credits_available": 18450,
  "credits_reserved": 550,
  "credits_used": 6000,
  "credits_per_month": 25000,
  "credits_used_percent": 26.2,
  "plan_expires": "2025-12-31 23:59:59",
  "max_concurrent_tasks": 3,
  "active_tasks": 1,
  "retention_days": 30,
  "threads": 4
}

Response fields

FieldTypeDescription
tariffstringPlan name (e.g. Free Trial, Pro, Enterprise)
credits_availableintegerCredits ready to use
credits_reservedintegerCredits held by pending/processing tasks
credits_usedintegerCredits consumed this billing cycle
credits_per_monthintegerMonthly credit quota (0 = unlimited)
credits_used_percentfloatcredits_used / credits_per_month × 100
plan_expiresstring|nullISO datetime of plan expiry, null if no expiry
max_concurrent_tasksintegerMaximum simultaneous tasks allowed
active_tasksintegerCurrently running or queued tasks
retention_daysintegerHow long results are stored
threadsintegerScraper threads allocated to the account

GET /v1/tasks

Returns a paginated list of tasks for the authenticated account.

Request

GET /api/v1/tasks?page=1&per_page=20&status=completed
X-Api-Key: as_live_your_key_here

Query parameters

ParameterTypeDefaultDescription
pageinteger1Page number
per_pageinteger20Results per page (max 100)
statusstringFilter by status: pending, processing, completed, failed

Response

{
  "success": true,
  "message": "Tasks fetched",
  "tasks": [
    {
      "id": 42,
      "status": "completed",
      "target_query": "nike shoes",
      "found_ads": 350,
      "credits_limit": 500,
      "credits_reserved": 0,
      "credits_spent": 350,
      "created_at": "2025-11-10 14:22:00",
      "updated_at": "2025-11-10 14:24:38"
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 20,
    "total": 87,
    "total_pages": 5
  }
}

Task status values

StatusDescription
pendingQueued, waiting for a scraper slot
processingActively scraping
completedFinished successfully
failedScraping failed

POST /v1/tasks

Creates a new scraping task. Credits are reserved immediately on creation and released or spent when the task finishes.

Request

POST /api/v1/tasks
X-Api-Key: as_live_your_key_here
Content-Type: application/json

Request body

{
  "query": "nike shoes",
  "credits_limit": 500,
  "filters": {
    "country": "US",
    "active_status": "ACTIVE",
    "media_type": "ALL",
    "search_type": "KEYWORD_UNORDERED",
    "sort_mode": "RELEVANCY_MONTHLY_GROUPED",
    "sort_direction": "DESCENDING",
    "publisher_platforms": ["facebook", "instagram"],
    "content_languages": "en",
    "advertiser_id": "",
    "start_date_min": "",
    "start_date_max": "",
    "result_count": 500,
    "get_eu_info": false,
    "is_targeted_country": false
  },
  "notifications": {}
}

Body fields

FieldTypeRequiredDescription
querystringYesSearch keyword or advertiser URL
credits_limitintegerNoMax credits to spend on this task. Clamped to 1–50000. Defaults to result_count from filters
filtersobjectNoSearch filters (see below)
notificationsobjectNoNotification config (Telegram, email)

filters object

FieldTypeDefaultAllowed values
countrystringALLISO 3166-1 alpha-2 code or ALL
active_statusstringACTIVEACTIVE, INACTIVE, ALL
media_typestringALLALL, IMAGE, VIDEO, MEME, IMAGE_AND_MEME, NONE
search_typestringKEYWORD_UNORDEREDKEYWORD_UNORDERED, KEYWORD_EXACT_PHRASE
sort_modestringRELEVANCY_MONTHLY_GROUPEDLAST_ACTIVITY_DATE, TOTAL_IMPRESSIONS, START_DATE, RELEVANCY_MONTHLY_GROUPED
sort_directionstringDESCENDINGDESCENDING, ASCENDING
publisher_platformsarrayall platformsfacebook, instagram, audience_network, messenger
content_languagesstring|arrayLanguage code(s), e.g. "en" or ["en","fr"]
advertiser_idstringNumeric Facebook Page ID to scope to a single advertiser
start_date_minstringYYYY-MM-DD — ads launched on or after this date
start_date_maxstringYYYY-MM-DD — ads launched on or before this date
result_countinteger50Target number of ads to collect (1–5000)
get_eu_infobooleanfalseInclude EU transparency data
is_targeted_countrybooleanfalseFilter by country of targeting (not ad origin)

Response (success)

{
  "success": true,
  "message": "Task created and added to queue",
  "task_id": 43,
  "credits_held": 500
}

Response fields

FieldTypeDescription
task_idintegerID to use when polling status or fetching results
credits_heldintegerCredits reserved from your balance (0 for Enterprise/unlimited plans)

Error codes

CodeHTTPDescription
CONCURRENT_LIMIT400Max simultaneous tasks reached; wait for a running task to complete
INSUFFICIENT_CREDITS400Not enough available credits to reserve for this task
RATE_LIMIT429Too many task creation requests (20 per 5 min / 100 per hour)

GET /v1/results

Returns paginated ad results for a completed (or in-progress) task.

Request

GET /api/v1/results?task_id=43&page=1&per_page=50
X-Api-Key: as_live_your_key_here

Query parameters

ParameterTypeRequiredDefaultDescription
task_idintegerYesTask ID returned by POST /v1/tasks
pageintegerNo1Page number
per_pageintegerNo50Results per page (max 100)

Response

{
  "success": true,
  "message": "Results fetched",
  "task": {
    "id": 43,
    "target_query": "nike shoes",
    "status": "completed",
    "found_ads": 350,
    "credits_reserved": 0,
    "created_at": "2025-11-10 14:22:00",
    "updated_at": "2025-11-10 14:24:38",
    "execution_time": "2m 38s"
  },
  "results": [
    {
      "id": 1001,
      "ad_archive_id": "123456789",
      "published_at": "2025-10-01 08:00:00",
      "stop_at": null,
      "page_id": "987654321",
      "page_name": "Nike",
      "page_url": "https://www.facebook.com/nike",
      "page_picture": "https://...",
      "captions": ["Just Do It"],
      "cta_text": ["Shop Now"],
      "cta_type": ["SHOP_NOW"],
      "display_format": "VIDEO",
      "links": ["https://nike.com/..."],
      "platforms": ["facebook", "instagram"],
      "body_text": ["Introducing the Air Max 2025..."],
      "link_description": ["New collection — limited time offer"],
      "images": ["https://..."],
      "videos": ["https://..."],
      "created_at": "2025-11-10 14:23:11"
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 50,
    "total": 350,
    "total_pages": 7
  }
}

Result object fields

FieldTypeDescription
ad_archive_idstringFacebook Ad Library unique identifier
published_atstring|nullWhen the ad started running
stop_atstring|nullWhen the ad stopped running (null = still active)
page_idstringFacebook Page ID of the advertiser
page_namestringAdvertiser page name
page_urlstringAdvertiser page URL
page_picturestringAdvertiser profile picture URL
captionsarrayAd caption texts
cta_textarrayCall-to-action button labels
cta_typearrayCTA type codes (e.g. SHOP_NOW, LEARN_MORE)
display_formatstringIMAGE, VIDEO, MEME, etc.
linksarrayDestination URLs in the ad
platformsarrayPlatforms the ad ran on
body_textarrayMain ad copy variants
link_descriptionarrayLink card descriptions
imagesarrayImage asset URLs
videosarrayVideo asset URLs

Error responses

All errors follow this shape:

{
  "success": false,
  "message": "Human-readable description",
  "code": "MACHINE_READABLE_CODE"
}

Common error codes

CodeHTTPDescription
AUTH_REQUIRED401Missing or invalid API key / session
API_KEY_LIMIT429API key daily request limit reached
NOT_FOUND404Resource not found or belongs to another account
METHOD_NOT_ALLOWED405Wrong HTTP method
RATE_LIMIT429Too many requests
SYSTEM_ERROR500Internal server error — contact support

Code examples

cURL

# Account info
curl -H "X-Api-Key: as_live_your_key" \
  https://adspyre.com/api/v1/account

# Create task
curl -X POST \
  -H "X-Api-Key: as_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{"query":"nike","credits_limit":200,"filters":{"country":"US","result_count":200}}' \
  https://adspyre.com/api/v1/tasks

# Poll task list
curl -H "X-Api-Key: as_live_your_key" \
  "https://adspyre.com/api/v1/tasks?status=completed&per_page=5"

# Fetch results
curl -H "X-Api-Key: as_live_your_key" \
  "https://adspyre.com/api/v1/results?task_id=43&per_page=50"

JavaScript (fetch)

const API_KEY = 'as_live_your_key';
const BASE    = 'https://adspyre.com/api';

const headers = { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json' };

// Create a task
const { task_id } = await fetch(`${BASE}/v1/tasks`, {
  method: 'POST',
  headers,
  body: JSON.stringify({
    query: 'nike shoes',
    credits_limit: 300,
    filters: { country: 'US', result_count: 300 },
  }),
}).then(r => r.json());

// Poll until completed
let status = 'pending';
while (status === 'pending' || status === 'processing') {
  await new Promise(r => setTimeout(r, 5000));
  const tasks = await fetch(`${BASE}/v1/tasks?per_page=1&page=1`, { headers }).then(r => r.json());
  status = tasks.tasks.find(t => t.id === task_id)?.status ?? status;
}

// Fetch results (page 1)
const data = await fetch(`${BASE}/v1/results?task_id=${task_id}&per_page=100`, { headers })
  .then(r => r.json());

console.log(data.results);

Python

import requests, time

API_KEY = "as_live_your_key"
BASE    = "https://adspyre.com/api"
HEADERS = {"X-Api-Key": API_KEY, "Content-Type": "application/json"}

# Create task
res = requests.post(f"{BASE}/v1/tasks", json={
    "query": "nike shoes",
    "credits_limit": 300,
    "filters": {"country": "US", "result_count": 300},
}, headers=HEADERS)
task_id = res.json()["task_id"]

# Poll until done
while True:
    tasks = requests.get(f"{BASE}/v1/tasks", params={"per_page": 100}, headers=HEADERS).json()
    task  = next((t for t in tasks["tasks"] if t["id"] == task_id), None)
    if task and task["status"] in ("completed", "failed"):
        break
    time.sleep(5)

# Fetch results
page, all_results = 1, []
while True:
    r = requests.get(f"{BASE}/v1/results", params={"task_id": task_id, "page": page, "per_page": 100}, headers=HEADERS).json()
    all_results.extend(r["results"])
    if page >= r["pagination"]["total_pages"]:
        break
    page += 1

print(f"Collected {len(all_results)} ads")

On this page