Authentication¶
Every request to the Marketing API must carry an access token. In the Nova Play sandbox each person receives a personal token from the instructor. The token identifies you, scopes the per-minute rate limit to you, and grants read access to all 10 Nova Play ad accounts. Tokens do not expire and cannot be refreshed or exchanged through the API.
Treat the token like a password: keep it in an environment variable (META_ACCESS_TOKEN
in all examples), never commit it to a repository, and remember that
paging.next URLs contain it.
Sending the token¶
The token can be sent in either of two ways. They are equivalent.
| Method | How | Notes |
|---|---|---|
| Query parameter | ?access_token=<token> |
This is how the Graph API traditionally works and how paging.next URLs are built. |
| HTTP header | Authorization: Bearer <token> |
Keeps the token out of URLs and logs. If both are present the query parameter wins. |
Query parameter¶
curl -G "https://graph.huydata.com/v21.0/me" \
-d "access_token=$META_ACCESS_TOKEN" \
-d "fields=id,name"
Authorization header¶
curl "https://graph.huydata.com/v21.0/me?fields=id,name" \
-H "Authorization: Bearer $META_ACCESS_TOKEN"
Both return the user node behind the token:
{
"id": "100000000000002",
"name": "Ads Sandbox User"
}
Verifying a token: GET /me¶
/me is the cheapest call to check that a token works. It counts against the rate limit
like any other request.
| Parameter | Type | Required | Description |
|---|---|---|---|
access_token |
string | yes (or Authorization header) |
Your personal token. |
fields |
string | no | Comma-separated list. Valid: id, name. Default id,name. |
Python example¶
import os
import requests
BASE = "https://graph.huydata.com/v21.0"
TOKEN = os.environ["META_ACCESS_TOKEN"]
resp = requests.get(
f"{BASE}/me/adaccounts",
params={"access_token": TOKEN, "fields": "id,name,account_id,currency"},
timeout=30,
)
body = resp.json()
if "error" in body:
raise RuntimeError(f"Graph API error {body['error']['code']}: {body['error']['message']}")
for account in body["data"]:
print(account["id"], account["name"])
Always inspect the JSON body for an error key rather than relying on the HTTP status
alone: every API error, including an invalid token and the rate limit, is returned with
HTTP status 400.
Authentication errors¶
| HTTP | code |
type |
When |
|---|---|---|---|
| 400 | 104 |
OAuthException |
No token was sent, neither as access_token nor as a Bearer header. |
| 400 | 190 |
OAuthException |
A token was sent but it is not a known token (typo, wrong platform, revoked). |
Missing token:
{
"error": {
"message": "An access token is required to request this resource.",
"type": "OAuthException",
"code": 104,
"fbtrace_id": "A4J_EQTPMXEW7jShSsHi7"
}
}
Invalid token:
{
"error": {
"message": "Invalid OAuth access token - Cannot parse access token",
"type": "OAuthException",
"code": 190,
"fbtrace_id": "AokyI0dkKgRSzsQdx1qqT"
}
}
The full list of error codes is on the Errors & rate limiting page.
Permissions¶
A token grants read access to all Nova Play ad accounts, campaigns, ad sets, ads and
insights. There is no write access: the API exposes GET only. Requests for an object id
that does not exist return error 100 with error_subcode 33
("Unsupported get request. Object with ID ... does not exist, cannot be loaded due to
missing permissions, or does not support this operation.").