Developer guide
Action AR API
A versioned REST API for branded, location-based collectible experiences. All endpoints live under /api/ar/v1 and return JSON.
1. Get a key
Create a partner account to generate a live key. It is shown once — store it in your backend's secrets. Keys are prefixed act_live_ and only the prefix is ever stored on our side.
2. Authenticate
Send your key as a bearer token on every request. Call the API from your backend — never ship a live key in browser JavaScript.
curl "https://action-tokens.com/api/ar/v1/pins/nearby?lat=38.627&lng=-90.199&radius=10000" \
-H "Authorization: Bearer $ACTION_AR_API_KEY"3. Create and place an experience
# Create reusable AR content
curl -X POST "https://action-tokens.com/api/ar/v1/experiences" \
-H "Authorization: Bearer $ACTION_AR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Grand Opening Balloon",
"mediaType": "image",
"mediaUrl": "https://cdn.example.com/balloon.png",
"ctaLabel": "Claim reward",
"ctaUrl": "https://example.com/reward"
}'# Drop it on the map. Re-POST the same externalId to move it.
curl -X POST "https://action-tokens.com/api/ar/v1/pins" \
-H "Authorization: Bearer $ACTION_AR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"experienceId": "<experience-id>",
"externalId": "beam_123",
"latitude": 38.627,
"longitude": -90.199,
"collectionRadiusM": 100,
"title": "Grand Opening",
"metadata": { "brand_id": "acme", "is_user_drop": false }
}'# Look up, move, or take down (id or externalId)
curl "https://action-tokens.com/api/ar/v1/pins/beam_123" \
-H "Authorization: Bearer $ACTION_AR_API_KEY"
curl -X PATCH "https://action-tokens.com/api/ar/v1/pins/beam_123" \
-H "Authorization: Bearer $ACTION_AR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "latitude": 40.7128, "longitude": -74.006 }'
curl -X DELETE "https://action-tokens.com/api/ar/v1/pins/beam_123" \
-H "Authorization: Bearer $ACTION_AR_API_KEY"Idempotency
For POST /experiences, /pins, /collections, and /bounties, send an Idempotency-Key header. Retries with the same key return the original response instead of creating a duplicate.
Filters, upsert, and metadata
GET /pins and GET /experiences accept externalId, isActive, metadata (JSON contains), cursor, and limit (max 200). Pins also accept bbox=minLng,minLat,maxLng,maxLat. Responses include meta.nextCursor.
POST with an externalId upserts: the existing row is updated and returned with meta.upserted: true instead of creating a duplicate. Store partner fields such as brand_id on pin metadata — nearby and collections return it.
Collect allows a partner GPS tolerance (default 15m, configurable in Settings) on top of each pin's radius.POST /launch is optional hosted AR; use media_url from nearby if you render AR yourself.
Webhooks
Set a webhook URL in the dashboard. We POST JSON for pin.created, pin.updated, pin.deleted, pin.collected, experience.created, and experience.updated. Verify X-Action-Signature as sha256= HMAC of the raw body with your signing secret.
Rate limits & CORS
Requests are rate limited per API key; responses include RateLimit-Remaining and RateLimit-Reset headers, and a 429 when exceeded. Add your site origins under Settings in the dashboard to allow browser calls; server-to-server requests have no origin restriction.
Hosted map & embed widget
In the dashboard Map tab, pick a custom URL. We host a branded map at /m/your-slug. To drop the same map on your site, copy the iframe — no API key in the browser.
<iframe
src="https://action-tokens.com/embed/your-slug"
title="Your map"
width="100%"
height="560"
style="border:0;border-radius:12px"
loading="lazy"
allow="geolocation"
></iframe>Public map JSON (no auth): GET /api/maps/your-slug
Endpoint reference
/api/ar/v1/experiencesCreate or upsert reusable image, video, or 3D model AR content.
/api/ar/v1/experiencesList experiences. Filters: externalId, isActive, metadata, cursor, limit.
/api/ar/v1/experiences/{id}Fetch one experience by UUID or externalId.
/api/ar/v1/experiences/{id}Update title, description, media, or metadata.
/api/ar/v1/pinsPlace a pin. Re-POSTing the same externalId moves that pin instead of duplicating it.
/api/ar/v1/pinsList pins. Filters: externalId, isActive, bbox, metadata, cursor, limit.
/api/ar/v1/pins/{id}Fetch one pin by UUID or externalId.
/api/ar/v1/pins/{id}Move or update a pin (lat/lng, radius, schedule, metadata, active).
/api/ar/v1/pins/{id}Remove a pin. Deactivates it if it already has collections.
/api/ar/v1/pins/nearbyNearby pins with media_url, metadata, title, and owner fields.
/api/ar/v1/collectionsVerify distance (radius + GPS tolerance) and collect a pin.
/api/ar/v1/collectionsA visitor's collection, or omit externalUserId for the partner-wide list.
/api/ar/v1/launchOptional hosted AR URL. Use nearby media_url if you render AR yourself.
/api/ar/v1/bountiesPost a bounty to the shared community map.
/api/ar/v1/bountiesList bounties you created via the API.
/api/ar/v1/bounties/nearbyDiscover active bounties near a location (lat, lng, radius).
Full machine-readable spec: OpenAPI JSON