Agilis API Documentation

The Agilis REST API lets advertisers manage offers programmatically. All requests are made over HTTPS to https://ads.agilis.dating and authenticated with your API key, supplied in the x-api-key request header. Responses are returned as JSON.

Developer Guide

The Agilis Advertising API lets developers create and manage advertiser offers programmatically. A typical integration starts by fetching available categories, estimating the price of an offer, creating the offer, then verifying and managing it through the offer management endpoints.

Recommended offer creation flow
1 Fetch categories using GET /categories
2 Estimate price using POST /offers/price-estimate
3 Create the offer using POST /offers
4 Verify the offer using GET /offers?environment=live or GET /offers?environment=test
5 Manage the offer using pause, resume, analytics, or delete endpoints

Payment methods

When creating an offer, use payment_method=E to generate a Stripe Checkout payment URL. The offer remains in Awaiting Payment status until Stripe confirms payment. After payment, the offer becomes Active if the start date is now or in the past, or Scheduled if the start date is in the future.

Use payment_method=B to pay from the organisation's Ad Unit balance. In this case, Ad Units are deducted immediately and no Stripe payment URL is returned.

Authentication

All requests require a valid API key in the x-api-key request header. API keys are managed in the Agilis Ad Portal under Manage API Keys. Invalid, disabled, or expired keys return 401 {"message": "Unauthorised"}.

Environment testing

Use environment=TEST when creating test offers. Test offers are only returned by GET /offers?environment=test and do not appear to real Agilis users. Use environment=LIVE for live campaigns.

Implementation notes

POST /offers is currently not idempotent. Developers should avoid blind retries on create requests because retrying after a timeout or network error may create duplicate offers. Idempotency support will be added in a future version.

Pagination and filtering are currently not supported for GET /offers. The endpoint returns the offers for the requested environment in a single response. Pagination and filtering support is planned for a future version.

Rate-limit headers may be returned by API responses, including successful and error responses: X-RateLimit-Limit shows the total requests allowed in the current window, and X-RateLimit-Remaining shows the requests remaining in the current window.

Category List

The Category List API returns all active categories available to the organisation that owns the API key. It is typically called before creating an offer, because offer creation requires a valid category ID returned by this endpoint.

Header: x-api-key: your_api_key_here
Method: GET

category_id integer

Unique ID of the category.
Example: 1

category_name string

Name of the category.
Example: "Retail"
Response codes
200 — Categories retrieved successfully.
401 — Invalid API key or disabled account.
500 — Internal server error.
GET /categories
import requests

url = "https://ads.agilis.dating/categories"
headers = {"x-api-key": "your_api_key_here"}

response = requests.get(url, headers=headers)
print(response.json())
Response (Python)

Create Offer

Creates a new offer for the authenticated advertiser. The request is sent as multipart/form-data with the offer image supplied as a binary file stream. The image is checked by automated content moderation before the offer is created.

Header: x-api-key: your_api_key_here
Content-Type: multipart/form-data

category_id integer, required

A valid category ID from the Category List API.
Example: 1

title string, required

Example: "20% off summer sale"

description string, required

Example: "Discount valid through July"

terms_and_conditions string, required

Maximum 500 characters.
Example: "Valid online only."

url string, required

Example: "https://advertiseroffer.com"

image binary, required

JPG, PNG or GIF, maximum 10MB, sent as a binary file stream.
Recommended size: 1080x1080px

currency string, required

One of GBP, USD, CAD, AUD (case-insensitive).

location[] array, required

Latitude and longitude as two values.
Example: [51.5074, -0.1278]

radius integer, required

Radius in miles, minimum 5.
Example: 10

start_datetime string, required

ISO 8601, UTC.
Example: "2026-07-10T08:00:00Z"

expiry_datetime string, required

ISO 8601, UTC.
Example: "2026-07-12T20:30:00Z"

payment_method string, required

E = Stripe payment link by email; B = deduct from organisation balance.

environment string, required

One of TEST or LIVE (case-insensitive).
Return codes
S1 — Offer created (payment link issued, or Live/Scheduled if paid from balance).
E1 — One or more inputs are missing or invalid (including unsupported currency).
E2 — The uploaded image was rejected by content moderation.
E3 — Insufficient Ad Unit balance.
POST /offers
import requests

url = "https://ads.agilis.dating/offers"
headers = {"x-api-key": "your_api_key_here"}

files = {
    "image": ("offer.jpg", open("/path/to/offer.jpg", "rb"), "image/jpeg")
}
data = {
    "category_id": 1,
    "title": "20% off summer sale",
    "description": "Discount valid through July",
    "terms_and_conditions": "Valid online only.",
    "url": "https://advertiseroffer.com",
    "currency": "GBP",
    "location[]": [51.5074, -0.1278],
    "radius": 10,
    "start_datetime": "2026-07-10T08:00:00Z",
    "expiry_datetime": "2026-07-12T20:30:00Z",
    "payment_method": "E",
    "environment": "LIVE"
}

response = requests.post(url, headers=headers, files=files, data=data)
print(response.json())
Response (Python)
{
  "return_code": "S1",
  "offer_id": 45,
  "status": "Awaiting Payment",
  "payment_url": "https://checkout.stripe.com/c/pay/cs_test_..."
}

View Offers

Returns all offers created by the authenticated advertiser for the requested environment. Offers whose image was rejected by content moderation are never created, so they are not returned.

Header: x-api-key: your_api_key_here
Method: GET

environment string, required

One of test or live (case-insensitive).
Example: /offers?environment=test

Each offer object contains: offer_id, title, category, description, terms_and_conditions, url, image (signed CloudFront URL), latitude, longitude, radius, gender (array such as ["Male","Female"], or null), start_datetime, expiry_datetime, creation_datetime and offer_status (Active, Paused, Ended or Awaiting Payment).

Response codes
200 — Offers returned (count is 0 with an empty array if none exist).
401 — Invalid API key or disabled account.
500 — Internal server error.
GET /offers?environment=test
import requests

url = "https://ads.agilis.dating/offers"
headers = {"x-api-key": "your_api_key_here"}
params = {"environment": "test"}

response = requests.get(url, headers=headers, params=params)
print(response.json())
Response (Python)
{
  "count": 1,
  "offers": [
    {
      "offer_id": 45,
      "title": "20% off summer sale",
      "category": "Retail",
      "description": "Discount valid through July",
      "terms_and_conditions": "Valid online only.",
      "url": "https://advertiseroffer.com",
      "image": "https://ads.agilis.dating/92/offers/45/offer_orig.png",
      "latitude": 51.5074,
      "longitude": -0.1278,
      "radius": 10,
      "gender": ["Male", "Female"],
      "start_datetime": "2026-07-10T08:00:00Z",
      "expiry_datetime": "2026-07-12T20:30:00Z",
      "creation_datetime": "2026-06-01T10:00:00Z",
      "offer_status": "Active"
    }
  ]
}

Pause and Resume Offer

Pauses a running offer or resumes a paused offer. These are two separate endpoints. The offer must belong to the account that owns the API key.

Header: x-api-key: your_api_key_here
Method: POST

offer_id integer, required

Path parameter.
Example: 45
Return codes
S1 — Offer paused successfully.
S2 — Offer resumed successfully.
E2 — Offer has already ended.
E3 — Offer is already paused (pause request).
E4 — Offer is already running (resume request).
E5 — Offer is awaiting payment.
POST /offers/{offer_id}/pause
import requests

headers = {"x-api-key": "your_api_key_here"}

# Pause an offer
pause = requests.post(
    "https://ads.agilis.dating/offers/45/pause", headers=headers)
print(pause.json())

# Resume an offer
resume = requests.post(
    "https://ads.agilis.dating/offers/45/resume", headers=headers)
print(resume.json())
Response (Python)
{
  "return_code": "S1",
  "message": "Offer has been paused."
}

Delete Offer

Deletes an offer belonging to the authenticated account. If the offer is awaiting payment, its Stripe payment link is disabled before deletion.

Header: x-api-key: your_api_key_here
Method: DELETE

offer_id integer, required

Path parameter.
Example: 45
Return codes
S1 — Offer deleted successfully.
E1 — Invalid input, or the offer does not belong to this account.
DELETE /offers/{offer_id}
import requests

url = "https://ads.agilis.dating/offers/45"
headers = {"x-api-key": "your_api_key_here"}

response = requests.delete(url, headers=headers)
print(response.json())
Response (Python)
{
  "return_code": "S1",
  "message": "Offer has been deleted."
}

View Offer Analytics

Returns view and click metrics for a specific offer over the requested time interval. The offer must belong to the account that owns the API key.

Header: x-api-key: your_api_key_here
Method: GET

offer_id integer, required

Path parameter.
Example: 45

interval string, required

One of 24h, 7d, 30d, 60d, 90d or all.
Response codes
200 — Analytics returned successfully.
401 — Invalid API key, disabled account, or offer not owned by this account.
500 — Internal server error.
GET /offers/{offer_id}/analytics
import requests

url = "https://ads.agilis.dating/offers/45/analytics"
headers = {"x-api-key": "your_api_key_here"}
params = {"interval": "30d"}

response = requests.get(url, headers=headers, params=params)
print(response.json())
Response (Python)
{
  "offer_id": 45,
  "interval": "30d",
  "start_datetime": "2026-07-10T08:00:00Z",
  "end_datetime": "2026-08-09T08:00:00Z",
  "status": "Active",
  "metrics": {
    "views": 4789,
    "clicks": 1032
  }
}

Offer Price Estimate

Calculates the price of an offer in Ad Units before it is created, based on the duration and the number of Agilis users within the target radius.

Header: x-api-key: your_api_key_here
Content-Type: application/json
Method: POST

start_datetime string, required

ISO 8601, UTC.
Example: "2026-07-10T08:00:00Z"

end_datetime string, required

ISO 8601, UTC.
Example: "2026-07-12T20:30:00Z"

location array, required

Latitude and longitude.
Example: [51.5074, -0.1278]

radius integer, required

Miles, minimum 5, maximum 30.
Example: 10
Return codes
S1 — Estimate calculated successfully.
E1 — One or more inputs are missing or invalid.
E2 — A date/time is not in valid ISO 8601 format.
POST /offers/price-estimate
import requests

url = "https://ads.agilis.dating/offers/price-estimate"
headers = {"x-api-key": "your_api_key_here"}
payload = {
    "start_datetime": "2026-07-10T08:00:00Z",
    "end_datetime": "2026-07-12T20:30:00Z",
    "location": [51.5074, -0.1278],
    "radius": 10
}

response = requests.post(url, headers=headers, json=payload)
print(response.json())
Response (Python)
{
  "return_code": "S1",
  "price_estimate": 45.50
}

Download

qr-code
appstore playstore
mobile-app-img

Socials

facebook instagram linkedin twitter tiktok
-->

We use cookies to enhance your browsing experience, serve personalized ads or content, and analyze our traffic. (View Cookie Policy)