Introduction

New Try the API Explorer. Browse every endpoint, read its parameters and responses, and issue live calls against your own account without writing any code.

It is generated from /api/openapi.json, which is derived from the API's own behaviour rather than written by hand, so unlike this page it cannot fall behind what the API actually does.

Open the API Explorer

The ads.txt Guru API allows you to control your account programmatically, this enables you to manage your domains, groups and ads.txt records using your own code, and most importantly enables you to streamline publisher aquisition by integrating the domain invite process into your publisher control panel.

HTTPS connections are used (HTTP connections are not permitted). These HTTPS connections are made to different URIs depending on the API function required, all of which must include the API protocol version. The API response is by default provided in JSON format, however the response can optionally be provided in PHP serialize() format, and optionally encoded using base64 encoding.

Every endpoint accepts POST. The endpoints that read one of your own objects also accept GET, and each endpoint below states which methods it takes directly under its name. validate/adstxt, validate/sellersjson and compare/adstxt are POST only despite changing nothing, because the file you send them does not fit in a URL. If you are writing new code, sending everything by POST always works and needs no reference to that list.

All API requests require your API key and secret which can be found under the Integrate section of your ads.txt Guru account. We recommend sending them as the X-API-Key and X-API-Secret request headers rather than as parameters, so that your credentials never appear in a URL (see Authentication).

This API also describes itself. An OpenAPI document covering every endpoint, parameter and response is published at /api/openapi.json (YAML), generated from the API's own behaviour rather than written by hand, so a client generator can consume it and it cannot fall behind this page. You can browse the same document, and issue live calls against your own account, in the API Explorer.

Note, we will be providing language specific libraries to simplify integration, beginning with a PHP library in the near future. Please contact us for more information.

If you have any questions regarding API integration, please contact us.

# Example listing domains

curl https://adstxt.guru/api/1.0/domain/list/
-d key=KEY
-d secret=SECRET


# Example response

{
    "success": true,
    "domains": {
        "1234": {
            "id": "1234",
            "tag": "abcdefgi01234567",
            "name": "domain.com",
            "protocol": "https",
            "verify_key": "ABCDEFGU01234567",
            "verified": "0",
            "comment": "1",
            "synchronize": "0",
            "discovery": "1"
        }
    }
}
$api = atg_api('KEY', 'SECRET');

Authentication

API authentication is handled using your API key and secret, these are required for all API requests. Your API key and secret can be found under the Integrate section of your ads.txt Guru account.

API access must be enabled in the Integrate section of your ads.txt Guru account in order to access the API.

Your credentials may be sent either as the X-API-Key and X-API-Secret request headers, or as the key and secret parameters. Headers are recommended. Parameters sent on a GET request travel in the URL, where they are recorded in web server access logs, in the logs of any intermediate proxy, and in a Referer header, so a long lived credential can end up in places you did not intend. The header form keeps the credential out of the URL whichever HTTP method you use. The parameters remain supported and are not being withdrawn without notice.

If both are supplied then the headers are used and the parameters are ignored. Both headers must be present to be used as a pair, otherwise the parameters are read as before.

If your request has failed authentication then a 401 HTTP status code will be returned.

Headers

X-API-Key: string (recommended)
Your 32 character API key.
X-API-Secret: string (recommended)
Your 32 character API secret.

Parameters

key: string (required if the X-API-Key header is not sent)
Your 32 character API key.
secret: string (required if the X-API-Secret header is not sent)
Your 32 character API secret.
format: string
json, json64, serial or serial64.
# Example request, credentials in headers (recommended)

curl https://adstxt.guru/api/1.0/
-H "X-API-Key: KEY"
-H "X-API-Secret: SECRET"


# Example request, credentials as parameters

curl https://adstxt.guru/api/1.0/
-d key=KEY
-d secret=SECRET


# Example authentication failed response

{
    "success": false,
    "reason": "authentication"
}
$api = atg_api('KEY', 'SECRET');

Responses & Errors

API responses are provided as arrays, either in JSON or PHP serialize() format.

The success value will always be included as true or false depending on the success of the request. The reason value will be returned when a request has not been successful, the core reasons are authentication, disabled and invalid, further reasons will be returned for specific functions.

API requests will typically be returned with a 200 HTTP status code, a 401 code will be returned when authentication has failed, a 400 code will be returned if the request was invalid, and a 429 code will be returned when the request has been rate limited (see Rate Limiting).

Unsuccessful reasons

authentication: Authentication has failed.
disabled: API access is disabled in the Integrate section of your ads.txt Guru account.
invalid: Request is invalid, either URI or parameters are incorrect.
rate-limit: Too many requests for this API key within the rate limit window. See Rate Limiting.
maintenance: API currently unavailable due to maintenance.
discontinued: API protocol version no longer supported.
# Example request

curl https://adstxt.guru/api/1.0/invalid/
-d key=KEY
-d secret=SECRET


# Example invalid request response

{
    "success": false,
    "reason": "invalid"
}
$api = atg_api('KEY', 'SECRET');

Rate Limiting

Heavyweight API endpoints are rate limited per API key to protect the service from accidental traffic bursts. Currently applies to validate/adstxt, validate/sellersjson and compare/adstxt. The two validate endpoints share their ceilings: wherever validate/adstxt is named below, a validate/sellersjson call with the same parameter counts against the same ceiling.

The window is 30 seconds, rolling, and what you may send inside it depends on how much work the call makes us do. validate/adstxt called with data is 150 calls per window per API key: it parses a file you already have, and fetches nothing. The two that fetch are 30 calls per window each, counted separately: compare/adstxt, which retrieves every domain you list, and validate/adstxt called with url, which retrieves the file itself.

There is a second ceiling on top of that one, and it is the first one expressed per second: 5 calls per second for validate/adstxt with data, and 1 call per second for the two that fetch. It takes away nothing you are allowed to send, because 150 per 30 seconds is 5 a second and 30 per 30 seconds is 1. What it stops is sending a window's worth all at once, which costs us far more than the same calls spread out and slows down every other client while it lands. If you pace at or below the per-second figure for the endpoint you are calling, you will never meet it.

A heavy paste caller therefore still has its full 30 fetches. When either is exceeded, the API returns a 429 HTTP status code with a rate-limit reason, and the headers below report the ceiling for the call you just made. If you have a legitimate use case that requires more, get in touch.

These ceilings are floors, not caps. They are what your key is guaranteed whatever else is happening, and we never serve you less. When the service has spare capacity we lend it out, so a call past your ceiling may be served instead of refused. A call served that way carries X-RateLimit-Surplus: 1, and only such a call carries it: the header is absent, never 0, on a call inside your own ceilings. On a borrowed call one of the Remaining headers reads 0 while the call still succeeds, which is how to tell it apart. Spare capacity is shared by every caller and moves with load from second to second, so treat a borrowed call as a loan rather than a new limit. Keep pacing to X-RateLimit-Burst, which always states your own ceiling and never the surplus: a client that raises its rate because a run of calls succeeded will meet 429s the moment the capacity it borrowed is needed elsewhere. When there is nothing to lend, you get exactly the ceilings above and a 429 past them.

The cheapest call is the one you do not make. Every compare/adstxt response carries a Cache-Control: private, max-age of its own, and that number is not a guess: it is the shortest time still left on the copies of the publisher files that answered the call, so it states exactly how long the body stays true. A client that honours it will not re-ask a question whose answer cannot have changed yet, which keeps it under both ceilings above without any pacing logic at all. It reads private because the body carries your own results and your own token balance, so it must never be held by a shared cache.

The two rate limited endpoints include these headers on every response, so a well-behaved client can pace itself rather than wait to be refused. No other endpoint emits them.

Response Headers

X-RateLimit-Limit: integer
Number of calls per window your key is guaranteed.
X-RateLimit-Remaining: integer
Calls remaining in the current window after this request.
X-RateLimit-Window-Seconds: integer
Length of the rate limit window in seconds.
X-RateLimit-Reset: integer
Unix timestamp at which the oldest call in the current window will expire and free up capacity.
X-RateLimit-Burst: integer
Number of calls in a single second your key is guaranteed, regardless of how much of the window above is unused.
X-RateLimit-Burst-Remaining: integer
Calls remaining in the current second after this request.
X-RateLimit-Burst-Window-Seconds: integer
Length of the burst window in seconds.
X-RateLimit-Surplus: integer (only on a borrowed call)
Always 1 when present. The call was past one of your ceilings and was served from spare capacity instead of refused. Absent on every other response. It says nothing about what you may send next, so keep pacing to X-RateLimit-Burst.
Retry-After: integer (only on 429)
Seconds to wait before retrying. This is the only header here defined by a standard (RFC 9110), and the one to build your retry logic on: it always names the wait for whichever ceiling refused the call.

429 Response Body

success: boolean
Always false for a rate-limit response.
reason: string
Always rate-limit, whichever ceiling refused the call.
ceiling: string
Which ceiling refused: sustained (the window) or burst (the single second). The limit, window_seconds, reset_unix and retry_after_seconds fields below all describe that ceiling, so you do not need to read this to retry correctly.
message: string
Human-readable explanation of the limit.
limit: integer
Maximum number of calls permitted per window.
remaining: integer
Always 0 in a rate-limit response.
window_seconds: integer
Length of the rate limit window in seconds.
reset_unix: integer
Unix timestamp at which the oldest call in the current window will expire.
retry_after_seconds: integer
Seconds to wait before retrying.
# Example rate limited response headers

HTTP/2 429
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 0
X-RateLimit-Window-Seconds: 30
X-RateLimit-Reset: 1715763600
X-RateLimit-Burst: 16
X-RateLimit-Burst-Remaining: 0
X-RateLimit-Burst-Window-Seconds: 1
Retry-After: 17


# Example rate limited response body

{
    "success": false,
    "reason": "rate-limit",
    "ceiling": "sustained",
    "message": "Too many requests for this API key. Limit is 30 calls per 30 seconds.",
    "limit": 30,
    "remaining": 0,
    "window_seconds": 30,
    "reset_unix": 1715763600,
    "retry_after_seconds": 17
}


# The same refusal from the BURST ceiling. Note Retry-After is 1, not 17:
# you are inside your window allowance, you just sent it too fast.

{
    "success": false,
    "reason": "rate-limit",
    "ceiling": "burst",
    "message": "Too many requests for this API key. Limit is 16 calls per 1 second.",
    "limit": 16,
    "remaining": 0,
    "window_seconds": 1,
    "reset_unix": 1715763584,
    "retry_after_seconds": 1
}
$api = atg_api('KEY', 'SECRET');

Paying for Calls

The stateless tools, validate/adstxt, validate/sellersjson and compare/adstxt, are paid for with tokens, bought in advance in the Integrate section of your account. No plan is needed: tokens alone are enough for those, on a free Basic account or on no subscription at all.

The rest of the API, the operations over your own domains, groups and records, is not metered at all, but it does need a plan that includes API access. Today that means the Ad Network plan: a Basic or Publisher account calling one of those endpoints is refused with a 403 and a subscription reason, whether or not it holds tokens.

If your plan already includes API access, nothing is metered for you and you do not need tokens at all, not even for the stateless tools. An Ad Network subscription covers the whole API, and calls made on it are never charged against a balance. Every authenticated response tells you which side of this you are on: X-Tokens-Metered: 0 means a subscription is covering the call.

Verify your email address and we credit 1,000 tokens, once, so you can build against the API before deciding anything. Tokens are valid for 365 days from your most recent purchase, and are sold to businesses only. The rates below are the rates we charge; the API Token Terms are the contract they sit under.

Token Cost

validate/adstxt with data 1 token
You hand us the file, so there is no outbound request to make.
validate/adstxt with url 2 tokens
We fetch the file from the address you give us, then parse it.
validate/sellersjson with data 1 token
You hand us the file, so there is no outbound request to make.
validate/sellersjson with url 2 tokens
We fetch the file from the domain you give us, following the specification's redirect rules, then check it.
compare/adstxt 1 token per domain in domains
Every entry in your list is a separate request we make to that domain's web server, so a call carrying a thousand domains costs us a thousand times what one carrying a single domain does.
Your own domains and groups 0 tokens
Not metered, but gated on an Ad Network plan rather than on tokens.

A call is charged when it runs, not when it succeeds. A domain that does not resolve, times out or serves nothing still costs us the request, so a stale list costs you real tokens. Knowing the weight of a job before you send it is the point of pricing this way.

What you are never charged for is work we did not do. A domain we decline to fetch, because it resolves to a private or reserved address, and one we ran out of time to reach before the call ended, are both settled back out of the cost. compare/adstxt answers with tokens_charged and tokens_not_charged so the reconciliation arrives with the results, beside the per-domain reason saying which were skipped and why. X-Tokens-Cost and X-Tokens-Balance state the settled figures, not the figures the call reserved, so a client pacing itself on those headers is reading the truth.

One compare/adstxt call carries at most 100 domains. That is the same limit for every caller, whatever your plan and whatever your balance: holding enough tokens for a longer list does not let you send it in a single request. Over the cap, nothing is fetched and nothing is charged - the call is refused with a domains-limit reason whose body states the cap as limit and what you sent as domains. Split a longer list across several calls; there is no cap on how many calls make up a job, only on the size of one.

Every authenticated response carries X-Tokens-Metered, and every metered call also carries its cost and your remaining balance, so a client can pace itself rather than wait to be refused.

Response Headers

X-Tokens-Metered: integer
1 if this key pays per call, 0 if a subscription covers it. Present on every authenticated response.
X-Tokens-Cost: integer (metered calls only)
Tokens this call cost.
X-Tokens-Balance: integer (metered calls only)
Tokens remaining after this call.

402 Response Body

A call your balance will not cover is refused with a 402 HTTP status code and a tokens reason. Nothing is charged and nothing is run, so the work can be retried unchanged once the balance is topped up.

success: boolean
Always false for a token response.
reason: string
Always tokens.
cost: integer
Tokens the refused call would have cost.
balance: integer
Tokens you hold.
shortfall: integer
Tokens you are short by, so a client can size a top-up without arithmetic.
# Example metered response headers

HTTP/2 200
X-Tokens-Metered: 1
X-Tokens-Cost: 3
X-Tokens-Balance: 9997


# Example 402 response body

{
    "success": false,
    "reason": "tokens",
    "cost": 3,
    "balance": 2,
    "shortfall": 1
}
$api = atg_api('KEY', 'SECRET');

Domain

The domain functions allow you to manage the domains which would normally be managed under the Manage section of your ads.txt Guru account.

These functions give you complete control to add, edit and remove your domains.

Domain data is provided in what we refer to as the Domain Array which includes the domain values as outlined below.

Domain Array

id: integer
Numeric domain ID.
tag: string
16 character domain tag.
name: string
The domain name.
protocol: string
The domain protocol, either https or http.
file: string
The file this domain manages, either ads.txt or app-ads.txt. Every URL associated with the domain refers to this file: the verification target, the hosted URL, the download filename. The same domain name may be added once for each file, giving you two independent domains with separate verification, delivery configuration and version history; this is the model the app-ads.txt standard itself describes. The file is fixed when the domain is added.
verify_key: string
16 character domain verification key.
verified: integer
0 if domain has not been verified, 1 if domain has been verified.
verify_version: string
The # Version header observed in the domain's live ads.txt at the last verification check, or an empty string if our header was absent. Advisory only — it never affects verified.
comment: integer
0 if comments will not be included in generated ads.txt file, 1 if comments will be included.
synchronize: integer
1 if automatic synchronization is enabled (requires 'Connect FTP' or 'Connect WordPress' is configured), 0 if not enabled.
discovery: integer
1 if domain can be discovered using domain tag, 0 if discovery is disabled.
# Example domain array

{
    "id": "1234",
    "tag": "abcdefgi01234567",
    "name": "domain.com",
    "protocol": "https",
    "file": "ads.txt",
    "verify_key": "ABCDEFGU01234567",
    "verified": "0",
    "verify_version": "",
    "comment": "1",
    "synchronize": "0",
    "discovery": "1"
}
$api = atg_api('KEY', 'SECRET');

domain/list

GET or POST

This function allows you to retrieve a list of all domains under your account.

Successful response values

success: boolean
true
domains: array
An array of Domain Arrays, each array record uses the domain ID as it's key.
# Example request

curl https://adstxt.guru/api/1.0/domain/list/
-d key=KEY
-d secret=SECRET


# Example successful response

{
    "success": true,
    "domains": {
        "1234": {
            "id": "1234",
            "tag": "abcdefgi01234567",
            "name": "domain.com",
            "protocol": "https",
            "verify_key": "ABCDEFGU01234567",
            "verified": "0",
            "comment": "1",
            "synchronize": "0",
            "discovery": "1"
        },
        "1235": {
            "id": "1235",
            "tag": "abcdefgi01234568",
            "name": "another.com",
            "protocol": "http",
            "verify_key": "ABCDEFGU01234568",
            "verified": "1",
            "comment": "1",
            "synchronize": "1",
            "discovery": "1"
        }
    }
}
$api = atg_api('KEY', 'SECRET');

domain/add

POST

This function allows you to add a new domain to your account.

Parameters

protocol: string
https or http.
name: string (required)
The domain name to be added, excluding the protocol. e.g. domain.com
file: string
ads.txt (default) or app-ads.txt. Adding an app-ads.txt domain requires a plan that includes app-ads.txt support. A domain name you already hold as ads.txt can be added again as app-ads.txt. The two are independent domains, and the pair only counts once against your domain allowance.

Unsuccessful reasons

invalid: Invalid name, protocol or file value.
duplicate: Domain has already been added under this account for this file. The same name for the other file is not a duplicate.
conflict: Domain has already been added under another account. This applies to both files: another account holding a name for either file blocks it for both.
permission: Your plan does not include app-ads.txt support. Only returned for file=app-ads.txt.
limit: Maximum domains limit reached. The limit counts domain names, so a name held for both files uses one.

Successful response values

success: boolean
true
domain: array
Domain Array.
first_domain: boolean
true when this was the first domain on the account, otherwise false. Useful for triggering onboarding in your own integration.
# Example request

curl https://adstxt.guru/api/1.0/domain/add/
-d key=KEY
-d secret=SECRET
-d protocol=https
-d name=domain.com
-d file=ads.txt


# Example duplicate domain response

{
    "success": false,
    "reason": "duplicate"
}


# Example successful response

{
    "success": true,
    "domain": {
        "id": "1234",
        "tag": "abcdefgi01234567",
        "name": "domain.com",
        "protocol": "https",
        "file": "ads.txt",
        "verify_key": "ABCDEFGU01234567",
        "verified": "0",
        "comment": "1",
        "synchronize": "0",
        "discovery": "1"
    },
    "first_domain": true
}
$api = atg_api('KEY', 'SECRET');

domain/get

GET or POST

This function allows you to retrieve a specific domain under your account.

In addition to the standard Domain Array fields, this function returns the time of the last verification check (verify_time, a unix timestamp) and an advisory version-currency signal. version_current is the ads.txt version we currently publish for the domain; version_status compares it against the version observed in the live ads.txt at the last check (verify_version) and is one of current (the live file is up to date), behind (we re-checked after publishing and the live file is still serving an older version — a stale copy), or unknown (not verified, or not yet re-checked since your last change, so we make no claim — a freshly edited domain reads unknown until the next check rather than falsely reporting behind). version_match is a convenience boolean, true only when version_status is current. These values are advisory only and never affect verified.

Parameters

domain: integer (required)
Numeric ID of domain you would like to retrieve.

Successful response values

success: boolean
true
domain: array
Domain Array.
# Example request

curl https://adstxt.guru/api/1.0/domain/get/
-d key=KEY
-d secret=SECRET
-d domain=1234


# Example successful response

{
    "success": true,
    "domain": {
        "id": "1234",
        "tag": "abcdefgi01234567",
        "name": "domain.com",
        "protocol": "https",
        "verify_key": "ABCDEFGU01234567",
        "verified": "1",
        "verify_time": "1780516541",
        "verify_version": "1.0.3",
        "comment": "1",
        "synchronize": "0",
        "discovery": "1",
        "version_current": "1.0.4",
        "version_status": "behind",
        "version_match": false
    }
}
$api = atg_api('KEY', 'SECRET');

domain/edit

POST

This function allows you to edit a domain under your account.

Parameters

domain: integer (required)
Numeric ID of domain you would like to edit.
protocol: string
https or http.
name: string
The new domain name, excluding the protocol. e.g. domain.com
comment: integer
0 if comments should not be included in generated ads.txt file, 1 if comments should be included.
synchronize: integer
1 if automatic synchronization should be enabled (requires 'Connect FTP' or 'Connect WordPress' is configured), 0 if should not be enabled.
discovery: integer
1 if domain should be discoverable using domain tag, 0 if discovery should be disabled.

Unsuccessful reasons

invalid: Invalid name or protocol value.
duplicate: Domain has already been added under this account.
conflict: Domain has already been added under another account.

Successful response values

success: boolean
true
domain: array
Domain Array.
# Example request

curl https://adstxt.guru/api/1.0/domain/edit/
-d key=KEY
-d secret=SECRET
-d domain=1234
-d protocol=http
-d comment=0


# Example successful response

{
    "success": true,
    "domain": {
        "id": "1234",
        "tag": "abcdefgi01234567",
        "name": "domain.com",
        "protocol": "http",
        "verify_key": "ABCDEFGU01234567",
        "verified": "0",
        "comment": "0",
        "synchronize": "0",
        "discovery": "1"
    }
}
$api = atg_api('KEY', 'SECRET');

domain/remove

POST

This function allows you to remove a specific domain under your account.

Parameters

domain: integer (required)
Numeric ID of domain you would like to remove.

Successful response values

success: boolean
true
# Example request

curl https://adstxt.guru/api/1.0/domain/remove/
-d key=KEY
-d secret=SECRET
-d domain=1234


# Example successful response

{
    "success": true
}
$api = atg_api('KEY', 'SECRET');

domain/synchronize

POST

This function allows you to provoke synchronization of a specific domain under your account.

This requires 'Connect FTP' or 'Connect WordPress' has been configured, although if neither are configured the API will retrieve the ads.txt file via HTTP to check it against the latest version, if matched then the synchronize is considered successful.

Parameters

domain: integer (required)
Numeric ID of domain you would like to synchronize.

Unsuccessful reasons

error: A system error has occurred.
noftp: 'Connect FTP' and 'Connect WordPress' have not been configured.
connect: FTP connection failed.
upload: Connection was successful, but FTP upload failed.
wordpress: WordPress connection failed, or the plugin refused the update. See detail below.

Unsuccessful response values

detail: string
Always present on an unsuccessful response. A more specific machine-readable code for the failure, or an empty string when there is nothing more specific to report. Read reason first and treat detail as a refinement of it: reason will not change value to describe a new detail, and new detail values may be added over time, so an unrecognised one should be handled as though it were empty.

When reason is wordpress, detail carries the reason reported by the ads.txt Guru Connect plugin itself: one of adstxt-unwritable, adstxt-path, adstxt-protected, adstxt-write, adstxt-check, adstxt-invalid, file-mismatch or connect-token. It is empty when the plugin could not be reached at all, or is older than 1.3.0. The first four all mean the file could not be written, most often because the configured path was left behind by a site move; open the ads.txt Guru page in the site's WordPress administration panel, which diagnoses the path and offers to repair it.

Successful response values

success: boolean
true
method: string
ftp, wordpress, or http will be returned if 'Connect FTP' is not configured but the ads.txt file has already been manually uploaded.
# Example request

curl https://adstxt.guru/api/1.0/domain/synchronize/
-d key=KEY
-d secret=SECRET
-d domain=1234


# Example 'Connect FTP' and 'Connect WordPress' not configured, and HTTP verification failed response

{
    "success": false,
    "reason": "noftp"
}


# Example WordPress plugin could not write the file response

{
    "success": false,
    "reason": "wordpress",
    "detail": "adstxt-unwritable"
}


# Example FTP synchronize successful response

{
    "success": true,
    "method": "ftp"
}


# Example HTTP verification successful response

{
    "success": true,
    "method": "http"
}
$api = atg_api('KEY', 'SECRET');

domain/verify

POST

This function allows you to provoke verification of a specific domain under your account.

Parameters

domain: integer (required)
Numeric ID of domain you would like to verify.

Successful response values

success: boolean
true
# Example request

curl https://adstxt.guru/api/1.0/domain/verify/
-d key=KEY
-d secret=SECRET
-d domain=1234


# Example successful response

{
    "success": true
}
$api = atg_api('KEY', 'SECRET');

domain/hosting

POST

This function enables Connect Hosting for a specific domain under your account, returning the hosted ads.txt URL. Direct your domain's /ads.txt path to this URL via 301 redirect and we will serve the latest version of your ads.txt automatically.

The endpoint is idempotent — calling it again for the same domain returns the same token and only updates the enabled flag if changed.

Parameters

domain: integer (required)
Numeric ID of domain you would like to enable hosting for.
enabled: integer (optional)
1 to enable hosting (default), 0 to disable.

Unsuccessful reasons

invalid: Domain ID is missing, not numeric, or not owned by the authenticated user.

Successful response values

success: boolean
true
hosting: array
Contains domain, token, enabled, and url.
# Example request

curl https://adstxt.guru/api/1.0/domain/hosting/
-d key=KEY
-d secret=SECRET
-d domain=1234


# Example successful response

{
    "success": true,
    "hosting": {
        "domain": 1234,
        "token": "AbCdEfGhIjKlMnOpQrStUvWxYz012345",
        "enabled": "1",
        "url": "https://adstxt.guru/hosting/AbCdEfGhIjKlMnOpQrStUvWxYz012345/ads.txt"
    }
}


# Example disable request

curl https://adstxt.guru/api/1.0/domain/hosting/
-d key=KEY
-d secret=SECRET
-d domain=1234
-d enabled=0
$api = atg_api('KEY', 'SECRET');

domain/wordpress

POST

This function connects a WordPress installation to a specific domain under your account, using the Connect Data generated by the ads.txt Guru WordPress plugin. Once connected, ads.txt updates are pushed to the WordPress site automatically.

The WordPress plugin generates the Connect Data as a base64-encoded string and displays it within the plugin's settings page. Pass this string verbatim to this endpoint.

This endpoint runs the same live handshake against the WordPress URL as the web UI — if the plugin URL cannot be reached or rejects our credentials, the connection is not saved and the response includes a reason.

Parameters

domain: integer (required)
Numeric ID of the domain to connect.
connect_data: string (required, unless disconnect=1)
Base64-encoded Connect Data string from the WordPress plugin.
disconnect: integer (optional)
1 to remove the existing WordPress connection for this domain.

Unsuccessful reasons

invalid: Domain ID is missing/not owned, or connect_data is missing/malformed/fails validation.
connect: Live handshake with the WordPress URL failed (no response or rejected credentials).
code-{HTTP_CODE}: The WordPress URL returned the given HTTP error code (e.g. code-403, code-404). Check the plugin URL is reachable and our IP is not blocked.

Successful response values

success: boolean
true
wordpress: array
Contains domain, url (when connecting), and connected (boolean).
# Example connect request

curl https://adstxt.guru/api/1.0/domain/wordpress/
-d key=KEY
-d secret=SECRET
-d domain=1234
-d connect_data=BASE64_BLOB_FROM_PLUGIN


# Example successful response

{
    "success": true,
    "wordpress": {
        "domain": 1234,
        "url": "https://example.com",
        "connected": true
    }
}


# Example disconnect request

curl https://adstxt.guru/api/1.0/domain/wordpress/
-d key=KEY
-d secret=SECRET
-d domain=1234
-d disconnect=1
$api = atg_api('KEY', 'SECRET');

Domain Group

The domain group functions allow you to manage the groups which can collaborate with your domain, you can also request new groups collaborate with your domain using collaborator tags.

These functions do not allow you to manage invitations to collaborate with groups, these are managed with the Domain Invite functions. For clarification, a domain can request collaboration with a group, whereas a group can invite a domain to collaborate.

Group data is provided in what we refer to as the Domain Group Array which includes the group relationship values as outlined below, this should not be confused with the Domain Array or Group Array.

Domain Group Array

id: integer
Numeric domain ID.
group: string
The group name.
trust: boolean/array
Returns false if group has not been certified, or an array containing organization and url values if the group is certified & trusted.
approved: integer
1 if collaboration with this group has been approved, 0 if collaboration has not yet been approved.
# Example domain group array

{
    "id": "1234",
    "group": "Example Group",
    "trust": {
        "organization": "Ad Network",
        "url": "http://example.com/"
    },
    "approved": "1"
}
$api = atg_api('KEY', 'SECRET');

domain/group/list

GET or POST

This function allows you to list the groups which are collaborating with this domain.

Parameters

domain: integer (required)
Numeric ID of domain.

Successful response values

success: boolean
true
groups: array
An array of Domain Group Arrays, each array record uses the request ID as it's key.
# Example request

curl https://adstxt.guru/api/1.0/domain/group/list/
-d key=KEY
-d secret=SECRET
-d domain=1234


# Example successful response

{
    "success": true,
    "groups": {
        "123": {
            "id": "123",
            "group": "Example Group",
            "trust": {
                "organization": "Ad Network",
                "url": "http://example.com/"
            },
            "approved": "1"
        },
        "124": {
            "id": "124",
            "group": "Another Group",
            "trust": false,
            "approved": "0"
        }
    }
}
$api = atg_api('KEY', 'SECRET');

domain/group/request

POST

This function allows you to request collaboration with a group using their collaborator tag. Requests require approval by the group, except when they have enabled automatic approval.

Collaborator tags are only accessible to the group owner, they must in turn share their collaborator tag with you to enable you to submit a request.

Parameters

domain: integer (required)
Numeric ID of domain.
tag: string (required)
16 character collaborator tag.
message: string
A message to help the group determine your eligibility to collaborate, maximum length is 255 characters, usage of certain characters/symbols is restricted.

Unsuccessful reasons

invalid-tag: Collaborator tag is invalid.
invalid-message: Invalid message, either it exceeds 255 characters or contains restricted characters/symbols.
duplicate: Duplicate request, collaboration with this group already exists or has already been requested.
limit: Maximum publishers limit reached.

Successful response values

success: boolean
true
request: array
Domain Group Array.
# Example request

curl https://adstxt.guru/api/1.0/domain/group/request/
-d key=KEY
-d secret=SECRET
-d domain=1234
-d tag=abcdefgi01234567
-d message=My+publisher+account+username+is+ABC123.


# Example invalid tag response

{
    "success": false,
    "reason": "invalid-tag"
}


# Example successful response

{
    "success": true,
    "request": {
        "id": "123",
        "group": "Example Group",
        "trust": false,
        "approved": "0"
    }
}
$api = atg_api('KEY', 'SECRET');

domain/group/remove

POST

This function allows you to remove a group to discontinue collaboration.

Parameters

domain: integer (required)
Numeric ID of domain.
group: integer (required)
Numeric ID of domain group request.

Successful response values

success: boolean
true
# Example request

curl https://adstxt.guru/api/1.0/domain/group/remove/
-d key=KEY
-d secret=SECRET
-d domain=1234
-d group=123


# Example successful response

{
    "success": true
}
$api = atg_api('KEY', 'SECRET');

Domain Invite

The domain invite functions allow you to view, approve and decline invitations you have received to collaborate with groups.

These functions do not allow you to manage existing group collaboration relationships, these are managed with the Domain Group functions. For clarification, a domain can request collaboration with a group, whereas a group can invite a domain to collaborate.

Invite data is provided in what we refer to as the Domain Invite Array which includes the invite relationship values as outlined below, this should not be confused with the Domain Array or Group Array. The Domain Invite Array follows the same format as the Domain Group Array with the addition of the message value.

Domain Invite Array

id: integer
Numeric domain ID.
group: string
The group name.
trust: boolean/array
Returns false if group has not been certified, or an array containing organization and url values if the group is certified & trusted.
approved: integer
1 if collaboration with this group has been approved, 0 if collaboration has not yet been approved.
message: string
A message from the group to help you determine the group's eligibility to collaborate.
# Example domain invite array

{
    "id": "1234",
    "group": "Example Group",
    "trust": {
        "organization": "Ad Network",
        "url": "http://example.com/"
    },
    "approved": "1",
    "message": "Request from ABC Ad Network as discussed with, john@abcads.com."
}
$api = atg_api('KEY', 'SECRET');

domain/invite/list

GET or POST

This function allows you to list the invitations you have received to collaborate with groups.

Parameters

domain: integer (required)
Numeric ID of domain.

Successful response values

success: boolean
true
invites: array
An array of Domain Invite Arrays, each array record uses the invite ID as it's key.
# Example request

curl https://adstxt.guru/api/1.0/domain/invite/list/
-d key=KEY
-d secret=SECRET
-d domain=1234


# Example successful response

{
    "success": true,
    "invites": {
        "123": {
            "id": "123",
            "group": "Example Group",
            "trust": {
                "organization": "Ad Network",
                "url": "http://example.com/"
            },
            "approved": "0",
            "message": "Request from ABC Ad Network as discussed with, john@abcads.com."
        },
        "124": {
            "id": "124",
            "group": "Another Group",
            "trust": false,
            "approved": "0",
            "message": ""
        }
    }
}
$api = atg_api('KEY', 'SECRET');

domain/invite/approve

POST

This function allows you to approve an invite. Once approved the invite becomes a domain group which can be managed with the Domain Group functions.

Parameters

domain: integer (required)
Numeric ID of domain.
invite: string (required)
Numeric ID of invite.

Successful response values

success: boolean
true
# Example request

curl https://adstxt.guru/api/1.0/domain/invite/approve/
-d key=KEY
-d secret=SECRET
-d domain=1234
-d invite=123


# Example successful response

{
    "success": true
}
$api = atg_api('KEY', 'SECRET');

domain/invite/decline

POST

This function allows you to decline an invite.

Parameters

domain: integer (required)
Numeric ID of domain.
invite: string (required)
Numeric ID of invite.

Successful response values

success: boolean
true
# Example request

curl https://adstxt.guru/api/1.0/domain/invite/decline/
-d key=KEY
-d secret=SECRET
-d domain=1234
-d invite=123


# Example successful response

{
    "success": true
}
$api = atg_api('KEY', 'SECRET');

Domain Adstxt

The domain adstxt functions allow you to manage your ads.txt records, for example to add new ads.txt records or to download your ads.txt file.

Adstxt data is provided in what we refer to as the Domain Adstxt Array which includes all your ads.txt records in array format. The Domain Adstxt Array is fundamentally the same as the Group Adstxt array.

Domain Adstxt Array

version: version
The numeric version number, e.g. 0.0.1.
records: array
An array of ads.txt records, as outlined below. Each array record uses the ads.txt record ID as it's key.

Domain Adstxt Array Records

tag: string
16 character tag used with the record ID to identify the record.
type: string
data, variable, comment or collaborator.
name: string
For data type, the domain name for the record.
For variable type, either contact, subdomain or inventorypartnerdomain.
For group type, the name of the group.
publisher: string (data type only)
Publisher ID.
relationship: string (data type only)
DIRECT or RESELLER.
certification: string (data type only)
Certification authority ID.
value: string (variable type only)
For contact name, the contact details such as an email address or contact form URL.
For subdomain name, the related subdomain such as blog.domain.com.
For inventorypartnerdomain name, the related domain such as domain.com.
comment: string (comment type only)
Comment text.
records: string (collaborator type only)
A sub-array of the Domain Adstxt Array Records including all records for the collaborator group.
# Example domain adstxt array

{
    "tag": "abcdefgi01234567",
    "type": "data",
    "name": "google.com",
    "publisher": "pub-0123456",
    "relationship": "DIRECT",
    "certification": "abcdef012345"
}
$api = atg_api('KEY', 'SECRET');

domain/adstxt/list

GET or POST

This function allows you to retrieve a list of all ads.txt records for a specific domain.

Parameters

domain: integer (required)
Numeric ID of domain.

Successful response values

success: boolean
true
adstxt: array
Domain Adstxt Array.
# Example request

curl https://adstxt.guru/api/1.0/domain/adstxt/list/
-d key=KEY
-d secret=SECRET
-d domain=1234


# Example successful response

{
    "success": true,
    "adstxt": {
        "version": "0.0.1",
        "records": {
            "123": {
                "tag": "abcdefgi01234567",
                "type": "data",
                "name": "google.com",
                "publisher": "pub-0123456",
                "relationship": "DIRECT",
                "certification": "abcdef012345"
            },
            "124": {
                "tag": "abcdefgi01234568",
                "type": "variable",
                "name": "contact",
                "value": "email@domain.com"
            },
            "125": {
                "tag": "abcdefgi01234569",
                "type": "comment",
                "comment": "Example comment."
            },
            "126": {
                "tag": "abcdefgi01234560",
                "type": "collaborator",
                "name": "Example Group",
                "records": {
                    "127": {
                        "tag": "abcdefgi01234561",
                        "type": "data",
                        "name": "google.com",
                        "publisher": "pub-0123457",
                        "relationship": "RESELLER",
                        "certification": "abcdef012345"
                    }
                }
            }
        }
    }
}
$api = atg_api('KEY', 'SECRET');

domain/adstxt/add

POST

This function allows you to add a new ads.txt record.

Parameters

domain: integer (required)
Numeric ID of domain.
type: string (required)
data, variable or comment.
name: string (required for data and variable types)
For data type, the domain name for the record.
For variable type, either contact, subdomain or inventorypartnerdomain.
publisher: string (required for data type)
Publisher ID.
relationship: string (required for data type)
DIRECT or RESELLER.
certification: string (data type only)
Certification authority ID.
value: string (required for variable type)
For contact name, the contact details such as an email address or contact form URL.
For subdomain name, the related subdomain such as blog.domain.com.
For inventorypartnerdomain name, the related domain such as domain.com.
comment: string (required for comment type)
Comment text.

Unsuccessful reasons

This function may return a reason value, or a reasons array containing multiple reasons.

error: A system error has occurred.
duplicate: A duplicate ads.txt record already exists.
name-incomplete: Name value not provided.
name-invalid: Name value is invalid. For a variable record on an app-ads.txt domain this also covers subdomain: the SUBDOMAIN variable is unused in app-ads.txt files and is not accepted there.
publisher-incomplete: Publisher ID not provided.
publisher-invalid: Publisher ID is invalid.
relationship-incomplete: Relationship not provided.
relationship-invalid: Relationship is invalid.
certification-invalid: Certification ID is invalid.
value-incomplete: Value not provided.
value-invalid: Value is invalid.
comment-incomplete: Comment not provided.
comment-invalid: Comment is invalid.

Successful response values

success: boolean
true
id: integer
Numeric ID for ads.txt record.
tag: string
16 character tag for ads.txt record.
# Example request

curl https://adstxt.guru/api/1.0/domain/adstxt/add/
-d key=KEY
-d secret=SECRET
-d domain=1234
-d type=data
-d name=google.com
-d publisher=pub-0123456
-d relationship=DIRECT
-d certification=abcdef012345


# Example invalid record response

{
    "success": false,
    "reasons": [
        "name-invalid",
        "publisher-invalid"
    ]
}


# Example successful response

{
    "success": true,
    "id": "123",
    "tag": "abcdefgi01234567"
}
$api = atg_api('KEY', 'SECRET');

domain/adstxt/edit

POST

This function allows you to edit an existing ads.txt record.

Parameters

domain: integer (required)
Numeric ID of domain.
record: integer (required)
Numeric ID of ads.txt record.
tag: string (required)
16 character tag for ads.txt record.
type: string (required)
data, variable or comment.
name: string (required for data and variable types)
For data type, the domain name for the record.
For variable type, either contact, subdomain or inventorypartnerdomain.
publisher: string (required for data type)
Publisher ID.
relationship: string (required for data type)
DIRECT or RESELLER.
certification: string (data type only)
Certification authority ID.
value: string (required for variable type)
For contact name, the contact details such as an email address or contact form URL.
For subdomain name, the related subdomain such as blog.domain.com.
For inventorypartnerdomain name, the related domain such as domain.com.
comment: string (required for comment type)
Comment text.

Unsuccessful reasons

This function may return a reason value, or a reasons array containing multiple reasons.

id-invalid: Invalid ads.txt record ID.
tag-invalid: Invalid ads.txt record tag.
error: A system error has occurred.
duplicate: A duplicate ads.txt record already exists.
name-incomplete: Name value not provided.
name-invalid: Name value is invalid. For a variable record on an app-ads.txt domain this also covers subdomain: the SUBDOMAIN variable is unused in app-ads.txt files and is not accepted there.
publisher-incomplete: Publisher ID not provided.
publisher-invalid: Publisher ID is invalid.
relationship-incomplete: Relationship not provided.
relationship-invalid: Relationship is invalid.
certification-invalid: Certification ID is invalid.
value-incomplete: Value not provided.
value-invalid: Value is invalid.
comment-incomplete: Comment not provided.
comment-invalid: Comment is invalid.

Successful response values

success: boolean
true
# Example request

curl https://adstxt.guru/api/1.0/domain/adstxt/edit/
-d key=KEY
-d secret=SECRET
-d domain=1234
-d record=123
-d tag=abcdefgi01234567
-d type=data
-d name=google.com
-d publisher=pub-0123456
-d relationship=DIRECT
-d certification=abcdef012345


# Example invalid record response

{
    "success": false,
    "reasons": [
        "name-invalid",
        "publisher-invalid"
    ]
}


# Example successful response

{
    "success": true
}
$api = atg_api('KEY', 'SECRET');

domain/adstxt/remove

POST

This function allows you to remove an existing ads.txt record.

Parameters

domain: integer (required)
Numeric ID of domain.
record: integer (required)
Numeric ID of ads.txt record.
tag: string (required)
16 character tag for ads.txt record.

Successful response values

success: boolean
true
# Example request

curl https://adstxt.guru/api/1.0/domain/adstxt/remove/
-d key=KEY
-d secret=SECRET
-d domain=1234
-d record=123
-d tag=abcdefgi01234567


# Example successful response

{
    "success": true
}
$api = atg_api('KEY', 'SECRET');

domain/adstxt/deduplicate

POST

This function removes duplicate comment lines from a domain's ads.txt, keeping the first occurrence of each. Data records are not affected, and inherited collaborator records are left untouched. The version history is preserved, so the change can be rolled back.

Parameters

domain: integer (required)
Numeric ID of domain.

Successful response values

success: boolean
true
removed_count: integer
Number of duplicate comment lines removed (0 if there were none).
version: string
The current ads.txt version number after the operation.
# Example request

curl https://adstxt.guru/api/1.0/domain/adstxt/deduplicate/
-d key=KEY
-d secret=SECRET
-d domain=1234


# Example successful response

{
    "success": true,
    "removed_count": 2,
    "version": "1.0.4"
}
$api = atg_api('KEY', 'SECRET');

domain/adstxt/delete_all

POST

This function removes all of a domain's own ads.txt records in a single call. Inherited collaborator group blocks are kept. The version history is preserved, so the change can be rolled back.

Parameters

domain: integer (required)
Numeric ID of domain.

Successful response values

success: boolean
true
deleted_count: integer
Number of records removed (0 if the domain had no own records).
version: string
The current ads.txt version number after the operation.
# Example request

curl https://adstxt.guru/api/1.0/domain/adstxt/delete_all/
-d key=KEY
-d secret=SECRET
-d domain=1234


# Example successful response

{
    "success": true,
    "deleted_count": 12,
    "version": "1.0.4"
}
$api = atg_api('KEY', 'SECRET');

domain/adstxt/import

POST

This function allows you to import an ads.txt file.

Parameters

domain: integer (required)
Numeric ID of domain.
import: string (required)
The contents of ads.txt file.

Successful response values

success: boolean
true
added_count: integer
Number of records added.
duplicate_count: integer
Number of lines ignored because the record was already present.
warning_count: integer
Number of lines which could not be imported, excluding duplicates.
warnings: array
An array of warnings, each array record uses the zero-based index of the submitted line as it's key, and contains msg (the reason), line (the submitted line, HTML encoded) and, on a duplicate only, duplicate. Note this is an empty JSON array ([]) when there are no warnings.
retry: string
The lines which were not imported, newline separated, excluding duplicates. Correct them and submit this value again.
# Example request

curl https://adstxt.guru/api/1.0/domain/adstxt/import/
-d key=KEY
-d secret=SECRET
-d domain=1234
-d import=google.com%2C+pub-0123456%2C+DIRECT%2C+abcdef012345%0A%23+A+Comment%0Acontact%3Demail%40domain.com


# Example successful response

{
    "success": true,
    "warnings": [],
    "warning_count": 0,
    "added_count": 3,
    "duplicate_count": 0,
    "retry": ""
}


# Example successful response, where a line could not be imported

{
    "success": true,
    "warnings": {
        "1": {
            "msg": "Duplicate data record ignored.",
            "duplicate": true,
            "line": "google.com, pub-0123456, DIRECT"
        },
        "2": {
            "msg": "Line not recognised as valid.",
            "line": "this is not a record"
        }
    },
    "warning_count": 1,
    "added_count": 1,
    "duplicate_count": 1,
    "retry": "this is not a record"
}
$api = atg_api('KEY', 'SECRET');

domain/adstxt/download

GET or POST

This function allows you to download an ads.txt file.

Parameters

domain: integer (required)
Numeric ID of domain.

Successful response values

success: boolean
true
adstxt: string
The content of the ads.txt file.
# Example request

curl https://adstxt.guru/api/1.0/domain/adstxt/download/
-d key=KEY
-d secret=SECRET
-d domain=1234


# Example successful response

{
    "success": true,
    "adstxt": "# ATG-ABCDEFGU01234567\n# Version 0.0.1\ngoogle.com, pub-0123456, DIRECT, abcdef012345\ncontact=email@domain.com"
}
$api = atg_api('KEY', 'SECRET');

Group

The group functions allow you to manage the groups which would normally be managed under the Collaborate section of your ads.txt Guru account.

These functions give you complete control to add, edit and remove your groups. These functions are only available to users with the 'Ad Network' membership plan, although we currently only allow API access under that plan.

Group data is provided in what we refer to as the Group Array which includes the group values as outlined below.

Group Array

id: integer
Numeric group ID.
tag: string
16 character group (collaborator) tag.
name: string
The group name.
trusted: integer
0 if group is not trusted, 1 if group is not trusted.
comment: integer
0 if comments will not be included in generated ads.txt file, 1 if comments will be included.
synchronize: integer
1 if automatic synchronization is enabled, 0 if not enabled.
discovery: integer
1 if group can be discovered using group (collaborator) tag, 0 if discovery is disabled.
approve: integer
1 if domain requests should be automatically approved, 0 if domain requires require approval.
managerdomain: string
The group's manager domain, or an empty string if not set. Emitted as a MANAGERDOMAIN= line on domains the group is applied to in reseller relationship mode.
# Example group array

{
    "id": "1234",
    "tag": "abcdefgi01234567",
    "name": "Example Group",
    "trusted": "0",
    "comment": "1",
    "synchronize": "0",
    "discovery": "1",
    "approve": "0",
    "managerdomain": "ad-network.example"
}
$api = atg_api('KEY', 'SECRET');

group/list

GET or POST

This function allows you to retrieve a list of all groups under your account.

Successful response values

success: boolean
true
groups: array
An array of Group Arrays, each array record uses the group ID as it's key.
# Example request

curl https://adstxt.guru/api/1.0/group/list/
-d key=KEY
-d secret=SECRET


# Example successful response

{
    "success": true,
    "groups": {
        "1234": {
            "id": "1234",
            "tag": "abcdefgi01234567",
            "name": "Example Group",
            "trusted": "0",
            "comment": "1",
            "synchronize": "0",
            "discovery": "1",
            "approve": "0"
        },
        "1235": {
            "id": "1235",
            "tag": "abcdefgi01234568",
            "name": "Another Group",
            "trusted": "0",
            "comment": "1",
            "synchronize": "1",
            "discovery": "1",
            "approve": "1"
        }
    }
}
$api = atg_api('KEY', 'SECRET');

group/add

POST

This function allows you to add a new group to your account.

Parameters

name: string (required)
The name of the group.

Unsuccessful reasons

invalid: Invalid name.
duplicate: Group has already been added under this account.
conflict: Group has already been added under another account.

Successful response values

success: boolean
true
group: array
Group Array.
# Example request

curl https://adstxt.guru/api/1.0/group/add/
-d key=KEY
-d secret=SECRET
-d name=Example Group


# Example duplicate domain response

{
    "success": false,
    "reason": "duplicate"
}


# Example successful response

{
    "success": true,
    "group": {
        "id": "1234",
        "tag": "abcdefgi01234567",
        "name": "Example Group",
        "trusted": "0",
        "comment": "1",
        "synchronize": "0",
        "discovery": "1",
        "approve": "0"
    }
}
$api = atg_api('KEY', 'SECRET');

group/get

GET or POST

This function allows you to retrieve a specific group under your account.

Parameters

group: integer (required)
Numeric ID of group you would like to retrieve.

Successful response values

success: boolean
true
group: array
Group Array.
# Example request

curl https://adstxt.guru/api/1.0/group/get/
-d key=KEY
-d secret=SECRET
-d group=1234


# Example successful response

{
    "success": true,
    "group": {
        "id": "1234",
        "tag": "abcdefgi01234567",
        "name": "Example Group",
        "trusted": "0",
        "comment": "1",
        "synchronize": "0",
        "discovery": "1",
        "approve": "0"
    }
}
$api = atg_api('KEY', 'SECRET');

group/edit

POST

This function allows you to edit a group under your account.

Parameters

group: integer (required)
Numeric ID of group you would like to edit.
name: string
The new group name.
comment: integer
0 if comments should not be included in generated ads.txt file, 1 if comments should be included.
synchronize: integer
1 if automatic synchronization should be enabled, 0 if should not be enabled.
discovery: integer
1 if group should be discoverable using group (collaborator) tag, 0 if discovery should be disabled.
approve: integer
1 if domain requests should be automatically approved, 0 if domain requires require approval.
managerdomain: string
Bare domain (e.g. ad-network.example) declared as this group's manager. When the group is applied to a domain in reseller relationship mode, a MANAGERDOMAIN= line pointing to this domain is added automatically. Pass an empty string to clear it. Omit the parameter to leave it unchanged.

Unsuccessful reasons

invalid: Invalid name.
invalid-managerdomain: The supplied manager domain is not a valid domain.
duplicate: Group has already been added under this account.
conflict: Group has already been added under another account.

Successful response values

success: boolean
true
group: array
Group Array.
# Example request

curl https://adstxt.guru/api/1.0/group/edit/
-d key=KEY
-d secret=SECRET
-d group=1234
-d comment=0
-d discovery=0

# Example successful response

{
    "success": true,
    "group": {
        "id": "1234",
        "tag": "abcdefgi01234567",
        "name": "Example Group",
        "trusted": "0",
        "comment": "0",
        "synchronize": "0",
        "discovery": "0",
        "approve": "0"
    }
}
$api = atg_api('KEY', 'SECRET');

group/remove

POST

This function allows you to remove a specific group under your account.

Parameters

group: integer (required)
Numeric ID of group you would like to remove.

Successful response values

success: boolean
true
# Example request

curl https://adstxt.guru/api/1.0/group/remove/
-d key=KEY
-d secret=SECRET
-d group=1234


# Example successful response

{
    "success": true
}
$api = atg_api('KEY', 'SECRET');

group/synchronize

POST

This function allows you to provoke synchronization of a specific group under your account.

Parameters

group: integer (required)
Numeric ID of group you would like to synchronize.

Unsuccessful reasons

error: A system error has occurred.
nosuccess: No domains were successfully synchronized.

Unsuccessful response values

detail: string
Always present on an unsuccessful response, and a refinement of reason in the same way as on domain/synchronize. A group synchronize reports the counts rather than any one domain's cause, so this is currently always an empty string here; synchronize a domain directly to see its own detail.
failed_count: integer
The number of domains which failed to be synchronized.

Successful response values

success: boolean
true
success_count: integer
The number of domains which were successfully synchronized.
failed_count: integer
The number of domains which failed to be synchronized.
# Example request

curl https://adstxt.guru/api/1.0/group/synchronize/
-d key=KEY
-d secret=SECRET
-d domain=1234


# Example 'nosuccess' response

{
    "success": false,
    "reason": "nosuccess",
    "failed_count": "5"
}


# Example successful response

{
    "success": true,
    "success_count": "5",
    "failed_count": "0"
}


# Example partially successful response

{
    "success": true,
    "success_count": "2",
    "failed_count": "3"
}
$api = atg_api('KEY', 'SECRET');

Group Domain

The group domain functions allow you to manage which domains the group can collaborate with, you can also invite new domains to a group using domain tags.

These functions do not allow you to manage requests from domains, these are managed with the Group Request functions. For clarification, a domain can request collaboration with a group, whereas a group can invite a domain to collaborate.

Domain data is provided in what we refer to as the Group Domain Array which includes the domain relationship values as outlined below, this should not be confused with the Domain Array or Group Array.

Group Domain Array

id: integer
Numeric group ID.
domain: string
The domain name.
flex: array
An array of values for this group's flex records.
approved: integer
1 if collaboration with this domain has been approved, 0 if collaboration has not yet been approved.
# Example group domain array

{
    "id": "1234",
    "domain": "domain.com",
    "flex": {
        "1-abcdefgi01234567": "pub-0123456"
    },
    "approved": "1"
}
$api = atg_api('KEY', 'SECRET');

group/domain/list

GET or POST

This function allows you to list the domains which are collaborating with this group.

Parameters

group: integer (required)
Numeric ID of group.

Successful response values

success: boolean
true
domains: array
An array of Group Domain Arrays, each array record uses the request ID as it's key.
# Example request

curl https://adstxt.guru/api/1.0/group/domain/list/
-d key=KEY
-d secret=SECRET
-d group=1234


# Example successful response

{
    "success": true,
    "domains": {
        "123": {
            "id": "123",
            "domain": "domain.com",
            "flex": {
                "1-abcdefgi01234567": "pub-0123456"
            },
            "approved": "1"
        },
        "124": {
            "id": "124",
            "domain": "example.com",
            "flex": {},
            "approved": "0"
        }
    }
}
$api = atg_api('KEY', 'SECRET');

group/domain/invite

POST

This function allows you to invite a domain to collaborate using the domain tag. All requests require approval by the domain.

Domain tags are only accessible to the domain owner, they must in turn share their domain tag with you to enable you to submit an invite.

Parameters

group: integer (required)
Numeric ID of group.
tag: string (required)
16 character domain tag.
message: string
A message to help the domain determine your eligibility to collaborate, maximum length is 255 characters, usage of certain characters/symbols is restricted.

Unsuccessful reasons

invalid-tag: Collaborator tag is invalid.
invalid-message: Invalid message, either it exceeds 255 characters or contains restricted characters/symbols.
duplicate: Duplicate request, collaboration with this domain already exists or has already been requested.
limit: Maximum publishers limit reached.

Successful response values

success: boolean
true
invite: array
Group Domain Array.
# Example request

curl https://adstxt.guru/api/1.0/group/domain/invite/
-d key=KEY
-d secret=SECRET
-d group=1234
-d tag=abcdefgi01234567
-d message=Request+from+Ad+Network+as+discussed+with%2C+john%40example.com.


# Example invalid tag response

{
    "success": false,
    "reason": "invalid-tag"
}


# Example successful response

{
    "success": true,
    "invite": {
        "id": "123",
        "domain": "domain.com",
        "flex": {},
        "approved": "0"
    }
}
$api = atg_api('KEY', 'SECRET');

group/domain/edit

POST

This function allows you to edit the flex record publisher ID values for a collaborating domain.

Parameters

group: integer (required)
Numeric ID of group.
domain: integer (required)
Numeric ID of group domain invite.
flex-ID-TAG: string (required)
This field must be submitted for each flex record which exists under this group, the ID and TAG values are taken from the Group Adstxt Array.

Unsuccessful reasons

ID-TAG: A separate reason will be returned for any invalid flex record values, the reason will be defined as the ID and TAG as taken from the Group Adstxt Array.

Successful response values

success: boolean
true
# Example request

curl https://adstxt.guru/api/1.0/group/domain/edit/
-d key=KEY
-d secret=SECRET
-d group=1234
-d domain=123
-d flex-1-abcdefgi01234567=pub-0123456

# Example unsuccessful response

{
    "success": false,
    "reasons": [
        "1-abcdefgi01234567"
    ]
}


# Example successful response

{
    "success": true
}
$api = atg_api('KEY', 'SECRET');

group/domain/relationship

POST

This function sets how a group's records render on one of its collaborating domains. The change is applied immediately, so the domain's ads.txt reflects it on the next read.

inherit: Each record renders exactly as authored on the group (default).
direct: Every data record is forced to DIRECT on this domain.
reseller: Every data record is forced to RESELLER on this domain, and the group's manager domain (if set) is added as a MANAGERDOMAIN= line.

Parameters

group: integer (required)
Numeric ID of group.
domain: integer (required)
Numeric ID of the domain (as returned by group/domain/list).
relationship: string (required)
One of inherit, direct or reseller.

Unsuccessful reasons

invalid: Invalid group, domain, or relationship value.

Successful response values

success: boolean
true
# Example request

curl https://adstxt.guru/api/1.0/group/domain/relationship/
-d key=KEY
-d secret=SECRET
-d group=1234
-d domain=123
-d relationship=reseller

# Example unsuccessful response

{
    "success": false,
    "reason": "invalid"
}


# Example successful response

{
    "success": true
}
$api = atg_api('KEY', 'SECRET');

group/domain/remove

POST

This function allows you to remove a domain to discontinue collaboration.

Parameters

group: integer (required)
Numeric ID of group.
domain: integer (required)
Numeric ID of group domain invite.

Successful response values

success: boolean
true
# Example request

curl https://adstxt.guru/api/1.0/group/domain/remove/
-d key=KEY
-d secret=SECRET
-d group=1234
-d domain=123


# Example successful response

{
    "success": true
}
$api = atg_api('KEY', 'SECRET');

Group Request

The group request functions allow you to view, approve and decline requests you have received to collaborate with domains.

These functions do not allow you to manage existing domain collaboration relationships, these are managed with the Group Domain functions. For clarification, a domain can request collaboration with a group, whereas a group can invite a domain to collaborate.

Request data is provided in what we refer to as the Group Request Array which includes the request relationship values as outlined below, this should not be confused with the Domain Array or Group Array. The Group Request Array follows the same format as the Group Domain Array with the addition of the message value.

Group Request Array

id: integer
Numeric group ID.
domain: string
The domain name.
approved: integer
1 if collaboration with this domain has been approved, 0 if collaboration has not yet been approved.
message: string
A message from the domain to help you determine the domain's eligibility to collaborate.
# Example group request array

{
    "id": "1234",
    "domain": "domain.com",
    "approved": "1",
    "message": "My publisher account username is ABC123."
}
$api = atg_api('KEY', 'SECRET');

group/request/list

GET or POST

This function allows you to list the requests you have received to collaborate with domains.

Parameters

group: integer (required)
Numeric ID of group.

Successful response values

success: boolean
true
requests: array
An array of Group Request Arrays, each array record uses the request ID as it's key.
# Example request

curl https://adstxt.guru/api/1.0/group/request/list/
-d key=KEY
-d secret=SECRET
-d domain=1234


# Example successful response

{
    "success": true,
    "requests": {
        "123": {
            "id": "123",
            "group": "domain.com",
            "approved": "0",
            "message": "My publisher account username is ABC123."
        },
        "124": {
            "id": "124",
            "group": "example.com",
            "approved": "0",
            "message": ""
        }
    }
}
$api = atg_api('KEY', 'SECRET');

group/request/approve

POST

This function allows you to approve a request. Once approved the request becomes a group domain which can be managed with the Group Domain functions.

Parameters

group: integer (required)
Numeric ID of group.
request: string (required)
Numeric ID of request.

Unsuccessful reasons

limit: Maximum publishers limit reached.

Successful response values

success: boolean
true
# Example request

curl https://adstxt.guru/api/1.0/group/request/approve/
-d key=KEY
-d secret=SECRET
-d group=1234
-d request=123


# Example successful response

{
    "success": true
}
$api = atg_api('KEY', 'SECRET');

group/request/decline

POST

This function allows you to decline a request.

Parameters

group: integer (required)
Numeric ID of group.
request: string (required)
Numeric ID of request.

Successful response values

success: boolean
true
# Example request

curl https://adstxt.guru/api/1.0/group/request/decline/
-d key=KEY
-d secret=SECRET
-d group=1234
-d request=123


# Example successful response

{
    "success": true
}
$api = atg_api('KEY', 'SECRET');

Group Adstxt

The group adstxt functions allow you to manage your ads.txt records, for example to add new ads.txt records or to download your ads.txt file.

Adstxt data is provided in what we refer to as the Group Adstxt Array which includes all your ads.txt records in array format. The Group Adstxt Array is fundamentally the same as the Domain Adstxt array, with the exception that 'collaborator' type records will not be included.

Group Adstxt Array

version: version
The numeric version number, e.g. 0.0.1.
records: array
An array of ads.txt records, as outlined below. Each array record uses the ads.txt record ID as it's key.

Group Adstxt Array Records

tag: string
16 character tag used with the record ID to identify the record.
type: string
data, flex, variable or comment.
name: string
For data and flex types, the domain name for the record.
For variable type, either contact, subdomain or inventorypartnerdomain.
For group type, the name of the group.
publisher: string (data type only)
Publisher ID.
relationship: string (data and flex types only)
DIRECT or RESELLER.
certification: string (data and flex types only)
Certification authority ID.
value: string (variable type only)
For contact name, the contact details such as an email address or contact form URL.
For subdomain name, the related subdomain such as blog.domain.com.
For inventorypartnerdomain name, the related domain such as domain.com.
comment: string (comment type only)
Comment text.
# Example group adstxt array

{
    "tag": "abcdefgi01234567",
    "type": "data",
    "name": "google.com",
    "publisher": "pub-0123456",
    "relationship": "DIRECT",
    "certification": "abcdef012345"
}
$api = atg_api('KEY', 'SECRET');

group/adstxt/list

GET or POST

This function allows you to retrieve a list of all ads.txt records for a specific group.

Parameters

group: integer (required)
Numeric ID of group.

Successful response values

success: boolean
true
adstxt: array
Group Adstxt Array.
# Example request

curl https://adstxt.guru/api/1.0/group/adstxt/list/
-d key=KEY
-d secret=SECRET
-d group=1234


# Example successful response

{
    "success": true,
    "adstxt": {
        "version": "0.0.1",
        "records": {
            "123": {
                "tag": "abcdefgi01234567",
                "type": "data",
                "name": "google.com",
                "publisher": "pub-0123456",
                "relationship": "DIRECT",
                "certification": "abcdef012345"
            },
            "124": {
                "tag": "abcdefgi01234568",
                "type": "variable",
                "name": "contact",
                "value": "email@domain.com"
            },
            "125": {
                "tag": "abcdefgi01234569",
                "type": "comment",
                "comment": "Example comment."
            }
        }
    }
}
$api = atg_api('KEY', 'SECRET');

group/adstxt/add

POST

This function allows you to add a new ads.txt record.

Parameters

group: integer (required)
Numeric ID of group.
type: string (required)
data, flex, variable or comment.
name: string (required for data, flex and variable types)
For data and flex type, the domain name for the record.
For variable type, either contact, subdomain or inventorypartnerdomain.
publisher: string (required for data type)
Publisher ID.
relationship: string (required for data and flex types)
DIRECT or RESELLER.
certification: string (data and flex types only)
Certification authority ID.
value: string (required for variable type)
For contact name, the contact details such as an email address or contact form URL.
For subdomain name, the related subdomain such as blog.domain.com.
For inventorypartnerdomain name, the related domain such as domain.com.
comment: string (required for comment type)
Comment text.

Unsuccessful reasons

This function may return a reason value, or a reasons array containing multiple reasons.

error: A system error has occurred.
duplicate: A duplicate ads.txt record already exists.
name-incomplete: Name value not provided.
name-invalid: Name value is invalid. For a variable record on an app-ads.txt domain this also covers subdomain: the SUBDOMAIN variable is unused in app-ads.txt files and is not accepted there.
publisher-incomplete: Publisher ID not provided.
publisher-invalid: Publisher ID is invalid.
relationship-incomplete: Relationship not provided.
relationship-invalid: Relationship is invalid.
certification-invalid: Certification ID is invalid.
value-incomplete: Value not provided.
value-invalid: Value is invalid.
comment-incomplete: Comment not provided.
comment-invalid: Comment is invalid.

Successful response values

success: boolean
true
id: integer
Numeric ID for ads.txt record.
tag: string
16 character tag for ads.txt record.
# Example request

curl https://adstxt.guru/api/1.0/group/adstxt/add/
-d key=KEY
-d secret=SECRET
-d group=1234
-d type=data
-d name=google.com
-d publisher=pub-0123456
-d relationship=DIRECT
-d certification=abcdef012345


# Example invalid record response

{
    "success": false,
    "reasons": [
        "name-invalid",
        "publisher-invalid"
    ]
}


# Example successful response

{
    "success": true,
    "id": "123",
    "tag": "abcdefgi01234567"
}
$api = atg_api('KEY', 'SECRET');

group/adstxt/edit

POST

This function allows you to edit an existing ads.txt record.

Parameters

group: integer (required)
Numeric ID of group.
record: integer (required)
Numeric ID of ads.txt record.
tag: string (required)
16 character tag for ads.txt record.
type: string (required)
data, flex, variable or comment.
name: string (required for data, flex and variable types)
For data and flex type, the domain name for the record.
For variable type, either contact, subdomain or inventorypartnerdomain.
publisher: string (required for data type)
Publisher ID.
relationship: string (required for data and flex type)
DIRECT or RESELLER.
certification: string (data and flex type only)
Certification authority ID.
value: string (required for variable type)
For contact name, the contact details such as an email address or contact form URL.
For subdomain name, the related subdomain such as blog.domain.com.
For inventorypartnerdomain name, the related domain such as domain.com.
comment: string (required for comment type)
Comment text.

Unsuccessful reasons

This function may return a reason value, or a reasons array containing multiple reasons.

id-invalid: Invalid ads.txt record ID.
tag-invalid: Invalid ads.txt record tag.
error: A system error has occurred.
duplicate: A duplicate ads.txt record already exists.
name-incomplete: Name value not provided.
name-invalid: Name value is invalid. For a variable record on an app-ads.txt domain this also covers subdomain: the SUBDOMAIN variable is unused in app-ads.txt files and is not accepted there.
publisher-incomplete: Publisher ID not provided.
publisher-invalid: Publisher ID is invalid.
relationship-incomplete: Relationship not provided.
relationship-invalid: Relationship is invalid.
certification-invalid: Certification ID is invalid.
value-incomplete: Value not provided.
value-invalid: Value is invalid.
comment-incomplete: Comment not provided.
comment-invalid: Comment is invalid.

Successful response values

success: boolean
true
# Example request

curl https://adstxt.guru/api/1.0/group/adstxt/edit/
-d key=KEY
-d secret=SECRET
-d group=1234
-d record=123
-d tag=abcdefgi01234567
-d type=data
-d name=google.com
-d publisher=pub-0123456
-d relationship=DIRECT
-d certification=abcdef012345


# Example invalid record response

{
    "success": false,
    "reasons": [
        "name-invalid",
        "publisher-invalid"
    ]
}


# Example successful response

{
    "success": true
}
$api = atg_api('KEY', 'SECRET');

group/adstxt/remove

POST

This function allows you to remove an existing ads.txt record.

Parameters

group: integer (required)
Numeric ID of group.
record: integer (required)
Numeric ID of ads.txt record.
tag: string (required)
16 character tag for ads.txt record.

Successful response values

success: boolean
true
# Example request

curl https://adstxt.guru/api/1.0/group/adstxt/remove/
-d key=KEY
-d secret=SECRET
-d group=1234
-d record=123
-d tag=abcdefgi01234567


# Example successful response

{
    "success": true
}
$api = atg_api('KEY', 'SECRET');

group/adstxt/import

POST

This function allows you to import an ads.txt file.

Parameters

group: integer (required)
Numeric ID of group.
import: string (required)
The contents of ads.txt file.

Successful response values

success: boolean
true
added_count: integer
Number of records added.
duplicate_count: integer
Number of lines ignored because the record was already present.
warning_count: integer
Number of lines which could not be imported, excluding duplicates.
warnings: array
An array of warnings, each array record uses the zero-based index of the submitted line as it's key, and contains msg (the reason), line (the submitted line, HTML encoded) and, on a duplicate only, duplicate. Note this is an empty JSON array ([]) when there are no warnings.
retry: string
The lines which were not imported, newline separated, excluding duplicates. Correct them and submit this value again.
# Example request

curl https://adstxt.guru/api/1.0/group/adstxt/import/
-d key=KEY
-d secret=SECRET
-d group=1234
-d import=google.com%2C+pub-0123456%2C+DIRECT%2C+abcdef012345%0A%23+A+Comment%0Acontact%3Demail%40domain.com


# Example successful response

{
    "success": true,
    "warnings": [],
    "warning_count": 0,
    "added_count": 3,
    "duplicate_count": 0,
    "retry": ""
}
$api = atg_api('KEY', 'SECRET');

group/adstxt/download

GET or POST

This function allows you to download an ads.txt file.

Parameters

group: integer (required)
Numeric ID of group.

Successful response values

success: boolean
true
adstxt: string
The content of the ads.txt file.
# Example request

curl https://adstxt.guru/api/1.0/group/adstxt/download/
-d key=KEY
-d secret=SECRET
-d group=1234


# Example successful response

{
    "success": true,
    "adstxt": "# ATG-ABCDEFGU01234567\n# Version 0.0.1\ngoogle.com, pub-0123456, DIRECT, abcdef012345\ncontact=email@domain.com"
}
$api = atg_api('KEY', 'SECRET');

Validate

The validate functions allow you to validate ads.txt files programmatically, either by providing the URL of an ads.txt file, or by providing the contents of an ads.txt file directly.

These functions are metered. Each call is charged against your token balance, and a call your balance will not cover is refused with a 402 before anything runs. See Paying for Calls for what each call costs. A subscription that includes API access covers them instead and is never charged against a balance.

Validation results for each line of the ads.txt file are provided in what we refer to as the Adstxt Validation Array which includes the values as outlined below.

validate/sellersjson checks the other file in the chain: the sellers.json an SSP, exchange or ad network publishes to say who each seller_id in its system is. Its results are a list of findings, each naming the IAB Tech Lab error code where one exists, described on its own entry.

Adstxt Validation Array

line: integer
ads.txt file line number.
type: string
The line type, either data, variable, comment, blank, invalid or unknown.
variable: string (variable type only)
contact, subdomain or inventorypartnerdomain.
duplicate: array
An array containing line numbers of matching duplicate records.
data: string
The contents of the line.
error: array
An array containing error reasons as outlined below. Errors are considered serious failures which must be resolved.
warning: array
An array containing warning reasons as outlined below. Warnings are points of concern which should be checked.
notice: array
An array containing notice reasons as outlined below. Notices highlight ways to improve the ads.txt formatting.
valid: interger
1 if the record is valid, or 0 if the record has at least one error, warning or notice.

Error reasons

line-invalid: Line is invalid and failed all validation.
data-format: Data record is formatted incorrectly (less than 3 or more than 4 parts).
data-domain-invalid: Data record domain is invalid.
data-publisher-invalid: Data record publisher ID is invalid.
data-relationship-invalid: Data record relationship value is invalid.
data-certification-invalid: Data record certification ID cannot be an identifier (empty, over 64 characters, or containing something other than letters, numbers, dots, hyphens and underscores).
data-certification-incorrect: Data record certification ID is incorrect.

Warning reasons

data-domain-invalid: Data record domain may be invalid.
data-certification-not-tagid: Data record certification ID is not a TAG-ID (16 hexadecimal characters). The specification sets no format for this field, so this is a warning and not an error.
variable-name-invalid: Variable name is invalid, must be 'CONTACT', 'SUBDOMAIN', 'INVENTORYPARTNERDOMAIN', 'OWNERDOMAIN' or 'MANAGERDOMAIN'.
variable-contact-invalid: Variable contact value is invalid.
variable-subdomain-invalid Variable subdomain value is invalid.
variable-inventorypartnerdomain-invalid Variable inventorypartnerdomain value is invalid.
variable-subdomain-unused The subdomain variable is unused in app-ads.txt files and will be ignored. Only returned when the file being validated is an app-ads.txt, which is known from a 'url' request.

Notice reasons

line-inline-comment: Line contains inline comment.
line-whitespace: Line contains unnecessary whitespace.
data-domain-case: Data record domain value contains uppercase characters.
data-domain-whitespace: Data record domain value contains unnecessary whitespace.
data-publisher-whitespace: Data record publisher ID contains unnecessary whitespace.
data-relationship-case: Data record relationship value contains lowercase characters.
data-relationship-whitespace: Data record relationship value contains unnecessary whitespace.
data-certification-whitespace: Data record certification ID value contains unnecessary whitespace.
comment-compatibility: Comment contains unusual characters/symbols, consider removing for compatibility.
variable-inventorypartnerdomain-adstxt: Inventory partner domains are followed to the partner's ads.txt file, not their app-ads.txt file. Only returned when the file being validated is an app-ads.txt, which is known from a 'url' request.

App-ads.txt Location Array

An app-ads.txt file is not read from the host you publish it on. A verifier takes the developer URL from your app store listing and derives a host from it, dropping labels on the way, so a file published on www.example.com is read by nobody: the app-ads.txt specification states that verifiers read example.com/app-ads.txt instead. Where the file you validated by url is an app-ads.txt, the response carries an appads array describing where a verifier will look for it.

host: string
The host of the URL you provided.
canonical: string
The host a verifier reads the file from first.
parent: string or false
The host a verifier falls back to when no file is found on canonical, or false where there is no distinct parent.
suffix: string
The public suffix matched in the host, e.g. co.uk.
suffix_known: boolean
false where that suffix is not in our Public Suffix List snapshot, in which case the rest is our best reading of the host rather than a certainty.
crawl_order: array
Every app-ads.txt URL a verifier tries, in the order it tries them: both schemes on canonical, then both on parent.
advice: array
An array of code / level / message arrays, as outlined below. Empty where the URL you provided is exactly where a verifier reads the file.

Location advice codes

appads-host-not-crawled: warning - no verifier reads app-ads.txt from the host you provided, so records published there are not seen at all. Publish at canonical.
appads-parent-fallback: notice - the file on canonical replaces the one on parent rather than adding to it, because the parent is read only when no file is found on the subdomain.
appads-suffix-unknown: notice - the public suffix in the host is not in our snapshot of the Public Suffix List.

Note the location advice is not counted in warning_count or notice_count: those totals are sums over the individual lines of the file, and this advice is about the file as a whole.

# Example adstxt validation array

{
    "line": 1,
    "type": "data",
    "duplicate": [
        "4",
        "17"
    ],
    "data": "domaincom  , 1234567, DIREC, abcdefghijk",
    "error": [
        "data-domain-invalid",
        "data-relationship-invalid"
    ],
    "warning": [
        "data-certification-not-tagid"
    ],
    "notice": [
        "data-domain-whitespace"
    ],
    "valid": "0"
}
# Example app-ads.txt location array
# (url=https://www.example.com/app-ads.txt)

{
    "host": "www.example.com",
    "canonical": "example.com",
    "parent": false,
    "suffix": "com",
    "suffix_known": true,
    "crawl_order": [
        "https://example.com/app-ads.txt",
        "http://example.com/app-ads.txt"
    ],
    "advice": [
        {
            "code": "appads-host-not-crawled",
            "level": "warning",
            "message": "Verifiers will not read app-ads.txt from www.example.com. ..."
        }
    ]
}
$api = atg_api('KEY', 'SECRET');

validate/adstxt

POST

This function allows you to validate a raw ads.txt file, either by providing the URL of an ads.txt file, or by providing the contents of an ads.txt file directly.

This function is metered. The call is charged against your token balance, and a call your balance will not cover is refused with a 402 before anything runs. See Paying for Calls for what it costs. A subscription that includes API access covers it instead and is never charged against a balance.

Parameters

data: string
The contents of an ads.txt file, up to 1 MB.
url: string (recommended method)
The full URL of an ads.txt file, e.g. http://domain.com/ads.txt A URL ending in app-ads.txt is validated as an app-ads.txt file and adds an App-ads.txt Location Array to the response.

Unsuccessful reasons

error: A system error has occurred.
empty-file: The ads.txt file is empty or contains only whitespace.
toolarge: ads.txt file is greater the 1 MB, the maximum size supported.
url-invalid: An invalid URL was provided.
url-connect: Connection to URL failed.

Successful response values

Note, the ads.txt file is considered valid if the error_count value is zero.

success: boolean
true
error_count: integer
The total number of errors detected.
warning_count: integer
The total number of warnings detected.
notice_count: integer
The total number of notices detected.
valid_count: integer
The total number of valid lines detected.
appads: array (app-ads.txt url only)
An App-ads.txt Location Array describing where a verifier will read the file from. Returned when the url you provided names an app-ads.txt file and a location can be derived from its host, and also returned alongside an unsuccessful url-connect reason, where it is often the explanation.
adstxt: array
An array of Adstxt Validation Arrays, each array record uses the line number as it's key.
# Example request

curl https://adstxt.guru/api/1.0/validate/adstxt/
-d key=KEY
-d secret=SECRET
-d url=http://domain.com/ads.txt


# Example successful response

{
    "success": true,
    "error_count": 1,
    "warning_count": 0,
    "notice_count": 1,
    "valid_count": 0,
    "adstxt": {
        "1": {
            "line": 1,
            "type": "data",
            "duplicate": [],
            "data": "example.com, abcdefg, DIRECT",
            "error": [],
            "warning": [],
            "notice": [],
            "valid": "1"
        },
        "2": {
            "line": 2,
            "type": "unknown",
            "duplicate": [],
            "data": " test",
            "error": [
                "line-invalid"
            ],
            "warning": [],
            "notice": [
                "line-whitespace"
            ],
            "valid": "0"
        }
    }
}
$api = atg_api('KEY', 'SECRET');

validate/sellersjson

POST

This function checks a sellers.json file, the file an SSP, exchange or ad network publishes to say who each seller_id in its system belongs to. Give it the advertising system's domain and it reads /sellers.json from there the way a buyer's crawler does, following the specification's redirect rules, or give it the contents of the file. It is the same check as the free sellers.json Validator, so the two always agree about a file.

This function is metered. The call is charged against your token balance, and a call your balance will not cover is refused with a 402 before anything runs. See Paying for Calls for what it costs. A subscription that includes API access covers it instead and is never charged against a balance. It shares the rate limits of validate/adstxt.

Parameters

data: string
The contents of a sellers.json file, up to 1 MB.
url: string (recommended method)
The domain of the advertising system, e.g. example.com, the first field of an ads.txt line: we read https://example.com/sellers.json, and http once if https does not answer. A full URL is read as given, so a file can be checked before it moves into place. Files up to 5 MB are read.

Unsuccessful reasons

error: A system error has occurred.
empty-file: The sellers.json you sent in data is empty or contains only whitespace. Nothing was charged.
toolarge: The sellers.json you sent in data is larger than 1 MB. For a larger file, send its domain as url instead.
url-invalid: The url is not something we will read, such as an IP address rather than a domain. message says why. Nothing was fetched and nothing was charged.
url-connect: The file could not be read. message says what happened, iab carries the IAB code where one applies (10010 for a status other than 2xx, 10030 for a file that does not arrive within 20 seconds, 10040 for more than five redirects within the domain, 10050 for a second redirect after the file was delegated), and fetch shows every request made.

Successful response values

The answer is a list of findings, errors first, then warnings, then notices. A finding is one kind of problem, however many sellers it applies to: it says how many in count and lists the first ten in examples, so the three counts count findings, not sellers.

success: boolean
true
outcome: string
The worst level found: error, warning, notice, or clean where there is nothing. invalid where the text is not JSON at all.
error_count: integer
The number of findings that are errors.
warning_count: integer
The number of findings that are warnings.
notice_count: integer
The number of findings that are notices.
fetch: array (url only)
url (what we read first), final_url (what answered, after any redirects), http_code, content_type (an empty string where the server sent none), seconds, and chain: every request made, in order, each a url and its HTTP code.
parsed: boolean
false where the text is not JSON.
summary: array
bytes, version, sellers, types (sellers of each seller_type), confidential, passthrough, domains (distinct seller domains), contact_email, contact_address and identifiers (their names).
findings: array
An array of Sellers.json Finding Arrays.
syntax: array or false
Where the text is not JSON and the parser could say where: line, column, message, and up to 40 characters before and after that point. false otherwise.

Sellers.json Finding Array

Build on a finding's key, level and iab. Its title and detail are written for people and may be reworded.

key: string
What kind of problem this is, one of the keys below.
level: string
error, warning or notice. Errors are what the specification requires and buyers' crawlers report; warnings are valid by the letter of it but cause trouble in practice; notices need no change.
iab: string
The IAB Tech Lab error code, or an empty string where the Tech Lab defines none. A duplicated seller_id carries both of its codes, as 12060 / 13060.
title: string
A one-line description.
detail: string
What the problem means and how to fix it.
count: integer
The number of sellers it applies to, or 1 for a problem with the file as a whole.
examples: array
Up to ten of the places it occurs, in file order, each with position (counting from 1), seller_id, value (the offending value written as JSON, cut to 120 characters) and suggestion (what it most likely should be, or an empty string). For seller-id-duplicate, each example is the repeat and its value the position of the entry it repeats.

Finding keys

content-type error 20020 Served with no Content-Type, or one other than application/json
https-unavailable warning Read over http, because https did not answer (a bare domain only)
delegated notice 10050 Redirected once to another root domain, which the specification allows
not-at-root warning 10010 Not at _/sellers.json_ at the root of the domain, where buyers read it
bom warning Starts with a byte order mark
json error 22010 Not JSON: empty, saved as UTF-16, or a syntax error, which syntax locates
parent error 21020 The top level is not an object
version error or warning 21020 No version, or not "1.0"; a warning where it is the number 1.0
sellers error or warning 21020 No sellers list, or not a list; a warning, with no code, where the list is empty
contact-email notice or warning No contact_email (a notice), or not an email address (a warning)
contact-address warning contact_address is not a string
identifiers warning identifiers is not a list, or an entry is not a name and value pair
ext warning The top level's ext is not an object
parent-keys notice The top level carries names the specification does not define
seller-not-object error 21030 An entry in sellers is not an object
seller-id-missing error 21030 A seller has no seller_id
seller-id-empty error 21030 A seller_id is empty
seller-id-type error 21030 A seller_id is not a string
seller-id-number warning A seller_id is a number, which loses leading zeros and precision
seller-id-whitespace warning A seller_id has spaces around it, so no ads.txt line matches it
seller-id-duplicate error 12060 / 13060 A seller_id is listed more than once; each example is the repeat, and its value the position of the entry it repeats
seller-type-missing error 21030 A seller has no seller_type
seller-type-invalid error 21050 A seller_type is not PUBLISHER, INTERMEDIARY or BOTH
seller-type-case notice A seller_type is not in capitals
is-confidential error 21060 is_confidential is not 0 or 1
is-passthrough error 21070 is_passthrough is not 0 or 1
name-missing error A seller that is not confidential has no name
name-type error A name is not a string
confidential-named warning A confidential seller is named anyway
domain-missing warning 21040 A seller that is not confidential has no domain
domain-type error 21010 A domain is not a string
domain-invalid error 21010 A domain is not a valid domain name
domain-url error 21010 A domain is a URL; the example's suggestion is the root domain
domain-not-root error 21010 A domain is not a root domain; the example's suggestion is the root
domain-whitespace warning 21010 A domain has spaces around it
domain-suffix warning 21010 A domain ends in a suffix the Public Suffix List does not know
comment-type warning A comment is not a string
seller-ext warning A seller's ext is not an object
seller-keys notice Sellers carry names the specification does not define

The codes are those of the IAB Tech Lab's published Supply Chain error code overview. IAB and IAB Tech Lab are trademarks of the Interactive Advertising Bureau, and ads.txt Guru is not affiliated with or endorsed by IAB Tech Lab.

# Example request

curl https://adstxt.guru/api/1.0/validate/sellersjson/
-d key=KEY
-d secret=SECRET
-d url=ssp.example.com


# Example successful response

{
    "success": true,
    "outcome": "error",
    "error_count": 1,
    "warning_count": 0,
    "notice_count": 0,
    "fetch": {
        "url": "https://ssp.example.com/sellers.json",
        "final_url": "https://ssp.example.com/sellers.json",
        "http_code": 200,
        "content_type": "application/json",
        "seconds": 0.38,
        "chain": [
            {
                "url": "https://ssp.example.com/sellers.json",
                "code": 200
            }
        ]
    },
    "parsed": true,
    "summary": {
        "bytes": 482,
        "version": "1.0",
        "sellers": 2,
        "types": {
            "PUBLISHER": 2,
            "INTERMEDIARY": 0,
            "BOTH": 0
        },
        "confidential": 0,
        "passthrough": 0,
        "domains": 2,
        "contact_email": "adops@ssp.example.com",
        "contact_address": false,
        "identifiers": []
    },
    "findings": [
        {
            "key": "domain-url",
            "level": "error",
            "iab": "21010",
            "title": "A \"domain\" is a URL, not a domain",
            "detail": "The spec asks for the root domain alone, ...",
            "count": 1,
            "examples": [
                {
                    "position": 2,
                    "seller_id": "pub-2",
                    "value": "\"https://www.example.com/\"",
                    "suggestion": "example.com"
                }
            ]
        }
    ],
    "syntax": false
}


# Example unsuccessful response

{
    "success": false,
    "reason": "url-connect",
    "message": "https://ssp.example.com/sellers.json returned HTTP 404 rather than the file. A sellers.json must be served with a 2xx status.",
    "iab": "10010",
    "fetch": {
        "url": "https://ssp.example.com/sellers.json",
        "final_url": "https://ssp.example.com/sellers.json",
        "http_code": 404,
        "content_type": "text/html",
        "seconds": 0.21,
        "chain": [
            {
                "url": "https://ssp.example.com/sellers.json",
                "code": 404
            }
        ]
    }
}
$api = atg_api('KEY', 'SECRET');

Compare

The compare functions allow you to verify whether specific ads.txt records are included in the ads.txt files of multiple domains. This functionality can be used to ensure your publishers have implemented specific ads.txt records.

These functions are metered. Every domain in your list is charged against your token balance, and a call your balance will not cover is refused with a 402 before anything runs. See Paying for Calls for what each call costs. A subscription that includes API access covers them instead and is never charged against a balance.

A single call carries at most 100 domains, the same limit for every caller regardless of plan or balance. Over it nothing is fetched and nothing is charged: the call is refused with a domains-limit reason, and that response states the limit and the number of domains you sent. Split a longer list across several calls; there is no limit on how many calls make up a job.

Comparison results are provided for each domain which is provided in what we refer to as the Adstxt Comparison Array which includes the values as outlined below.

Adstxt Comparison Array

domain: string
The domain name which was provided.
id: string
The ID for the domain (if provided).
url: string
The URL which was checked - this is the domain name, including the protocol used and the filename that was read ('ads.txt', or 'app-ads.txt' where the domains entry asked for it).
status: string
success, missing or failed.
missing: array
An array containing all missing records.
error: string
An error message, if applicable.
reason: string
A detailed explanation for the error message, if applicable.
fetched_at: integer (only where the file was read)
The unix timestamp at which we actually read this domain's file. Absent for a domain we never managed to read, because there is no read to report.
age: integer (only where the file was read)
Seconds between that read and this response. 0 means we fetched the file for this call. Anything higher means we answered from a copy we already held: we keep a publisher's file for a short time, and honour that publisher's own Cache-Control or Expires where they set one, so a repeated question does not send their server a repeated request. The response always says which you got, so a client that needs a live read can check this field.
# Example adstxt comparison array

{
    "domain": "example.com",
    "id": "CUSTOM-ID",
    "url": "http://example.com/ads.txt",
    "status": "missing",
    "missing": [
        "domain.com, 123456, DIRECT"
    ],
    "error": "",
    "reason": "",
    "fetched_at": 1789856084,
    "age": 0
}
$api = atg_api('KEY', 'SECRET');

compare/adstxt

POST

This function allows you to verify whether specific ads.txt records are included in the ads.txt files of multiple domains.

This function is metered. Every domain in your list is charged against your token balance, and a call your balance will not cover is refused with a 402 before anything runs. See Paying for Calls for what it costs. A subscription that includes API access covers it instead and is never charged against a balance.

A single call carries at most 100 domains, the same limit for every caller regardless of plan or balance. Over it nothing is fetched and nothing is charged: the call is refused with a domains-limit reason whose response states the cap as limit and what you sent as domains. Split a longer list across several calls; there is no limit on how many calls make up a job.

Parameters

adstxt: string (required)
The ads.txt records which you would like to check are present on the specified domains, formatted as a standard ads.txt file. Only data records will be compared - variables and comments will be ignored.
domains: string (required)
A list of domains to check. Each domain can include a protocol (http or https); if not included then https is used. The file is always read from the root of the domain, so any directories in a path are ignored - but ending an entry with 'app-ads.txt' checks that domain's app-ads.txt file instead of its ads.txt. A unique ID can be included after each domain separated by a comma - this ID is then returned in the results to assist with processing.

Unsuccessful reasons

adstxt-toolarge: ads.txt input must be less than 1 MB.
adstxt-error: Unable to process ads.txt input.
domains-toolarge: Domains input must be less than 1 MB.
domains-error: Unable to process domains input.
domains-limit: Domains input carries more than the 100 domains allowed in one call. The response states the cap as limit and the number you sent as domains. Nothing was fetched and nothing was charged.

Successful response values

success: boolean
true
matched_count: integer
The total number of domains which matched all records.
partial_count: integer
The total number of domains which were missing some or all records.
failed_count: integer
The total number of domains with errors such as connection errors or non-existent ads.txt files.
results: array
An array of Adstxt Comparison Arrays for each domain being checked.
tokens_charged: integer (metered calls only)
Tokens this call actually took, after any domain we did not fetch was credited back. See Paying for Calls.
tokens_not_charged: integer (metered calls only)
Domains in your list we did not fetch, and so did not charge for. Each one carries a reason in its result saying why.
# Example request

curl https://adstxt.guru/api/1.0/compare/adstxt/
-d key=KEY
-d secret=SECRET
-d adstxt=domain.com, 12345, DIRECT
-d domains=example.com,EXAMPLE-ID\n
    http://www.missing.com\n
    subdomain.failed.com


# Example successful response

{
    "success": true,
    "matched_count": 1,
    "partial_count": 1,
    "failed_count": 1,
    "results": [
        {
            "domain": "example.com",
            "id": "EXAMPLE-ID",
            "url": "https://example.com/ads.txt",
            "status": "success",
            "missing": [],
            "error": "",
            "reason": "",
            "fetched_at": 1789856084,
            "age": 0
        },
        {
            "domain": "http://missing.com",
            "id": "ID",
            "url": "https://www.missing.com/ads.txt",
            "status": "missing",
            "missing": [
                "domain.com, 12345, DIRECT"
            ],
            "error": "",
            "reason": "",
            "fetched_at": 1789854284,
            "age": 1800
        },
        {
            "domain": "subdomain.failed.com",
            "id": "",
            "url": "https://subdomain.failed.com/ads.txt",
            "status": "failed",
            "missing": [],
            "error": "Connection error",
            "reason": "Your URL returned a 404 File Not Found error indicating an ads.txt file can not be found."
        }
    ]
}
$api = atg_api('KEY', 'SECRET');