Guide
Everything you need to actually use Endcap, whether you run the marketplace or you're advertising on one.
On this page
Getting your account
Two ways to get one, depending on which applies to you:
- New to Endcap? Sign up yourself — this creates your marketplace's account with you as its owner, no one else needed.
- Joining an existing marketplace's account? An owner there invites you by email, with a link to set your password. If you're expecting that and haven't received it, ask them to send it — see "Inviting people" under Using the API, below.
Logging in
Go to /login, enter your email and password, and you'll land on your dashboard. Password reset exists as an API call, but outgoing email isn't configured on this account yet, so a reset link won't actually arrive — if you're locked out, contact whoever owns your account directly for now.
Your dashboard
After logging in you'll see:
- Your name and email.
- Which marketplace ("tenant") you're acting as, and your role there. If you belong to more than one, a dropdown lets you switch.
- Your subscription status — owners and viewers only; advertisers won't see this.
- Your publisher key — the identifier your marketplace's own site uses to request sponsored listings. See Embedding, below.
- Your API token — click "Show token" to reveal it. This authenticates every API request in this guide.
Roles
| Role | Can do |
|---|---|
| Owner | Everything: products, placements, campaigns, team members, billing, privacy requests, refunds. |
| Viewer | See everything an owner can see. Can't change anything. |
| Advertiser | Create and manage only their own campaigns, and browse the product catalogue. No access to placements, billing, or other people's campaigns. |
Using the API
There's no web interface yet for the things below — the API is the only way to do them today. Every request needs:
Authorization: Bearer YOUR_API_TOKEN
Accept: application/json
X-Tenant-Id: YOUR_TENANT_ID
X-Tenant-Id is only required if you belong to more than one marketplace — find both values on your dashboard.
One thing that trips people up: money amounts are always in minor units — pence, not pounds. £2.50 is 250.
Viewing your campaigns
curl https://endcap.co.uk/api/v1/campaigns \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
Creating a campaign
Owners can create a campaign for anyone; advertisers always create one for themselves, regardless of what they submit.
curl -X POST https://endcap.co.uk/api/v1/campaigns \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Spring Sale",
"advertiser_id": "acme-corp",
"bid_minor": 25,
"daily_budget_minor": 5000,
"total_budget_minor": 100000,
"currency": "GBP",
"starts_at": "2026-09-08T00:00:00Z",
"product_ids": ["<product-uuid>"]
}'
That example bids 25p per click, capped at £50/day and £1,000 total.
Checking performance
curl https://endcap.co.uk/api/v1/reports/campaigns/CAMPAIGN_ID \
-H "Authorization: Bearer YOUR_API_TOKEN"
Returns impressions, clicks, and spend, broken down by day.
Adding products to your catalogue (owners only)
curl -X POST https://endcap.co.uk/api/v1/products \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"external_id": "sku-1234",
"title": "Wireless Headphones",
"vendor_id": "acme-corp",
"url": "https://yourmarketplace.com/products/sku-1234",
"price_minor": 4999,
"currency": "GBP"
}'
Setting up a placement (owners only)
A placement is a spot on your site where sponsored listings can appear — a search page, a category page, and so on.
curl -X POST https://endcap.co.uk/api/v1/placements \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"key": "search-results", "name": "Search results page", "maximum_ads": 3}'
Inviting people onto your account (owners only)
curl -X POST https://endcap.co.uk/api/v1/tenant-users \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Jane Smith", "email": "jane@example.com", "role": "advertiser"}'
role is one of owner, viewer, or advertiser. A brand-new email address gets sent a link to set their password — again, this needs outgoing email configured to actually arrive.
Refunding an invalid click (owners only)
curl -X POST https://endcap.co.uk/api/v1/ledger-entries \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"type": "refund", "ad_event_id": 12345, "currency": "GBP", "reason": "Suspected bot traffic"}'
This reverses the charge, restores that campaign's budget by the same amount, and marks the click as refunded so it can't be refunded twice. One current gap: there's no listing endpoint yet that shows you individual ad_event_id values to find one — for now that needs a direct look at the data. Worth asking for if you'll use this regularly.
Embedding sponsored listings on your site
Once you have a placement and at least one active campaign, add this to your site:
<script src="https://endcap.co.uk/sdk.js"></script>
<script>
const listings = new SponsoredListings({
endpoint: 'https://endcap.co.uk',
publisherKey: 'YOUR_PUBLISHER_KEY',
});
listings.request({ placement: 'search-results', query: 'running shoes', limit: 3 })
.then(({ ads }) => {
const container = document.querySelector('#sponsored-slot');
ads.forEach(ad => listings.render(container, ad));
});
</script>
render() gives you a plain, clearly-labelled "Sponsored" link — enough to get started. To show a product image or price instead, read the fields directly off each ad — title, url, image_url, price_minor, currency — and build your own markup rather than calling render().
By default, no visitor identifier is collected at all. If you want click measurement tied to a pseudonymous visitor ID instead, pass consentBasis: 'consent' and your own visitorId — but only once you've established a proper lawful basis, and consent where PECR requires it. See the Privacy & Cookie Notice.
Billing
Subscribing
curl -X POST https://endcap.co.uk/api/v1/billing/checkout \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"plan": "monthly"}'
plan is monthly or annual. The response includes a checkout_url — open it in a browser to enter payment details with Stripe.
Check your status any time with GET /api/v1/billing/subscription (also shown on your dashboard). Cancel with POST /api/v1/billing/cancel — this takes effect at the end of your current billing period, not immediately. If a payment fails, campaign and product management pauses until it's resolved, but your existing data stays visible the whole time.
Privacy requests
If someone asks you to access or delete the data Endcap holds about them (owners only):
curl -X POST https://endcap.co.uk/api/v1/privacy-requests \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"type": "delete", "visitor_id": "their-visitor-id"}'
This doesn't act on anything yet — it sits pending until you've confirmed the person's identity yourself, outside Endcap, and then call:
curl -X PATCH https://endcap.co.uk/api/v1/privacy-requests/REQUEST_ID/verify \
-H "Authorization: Bearer YOUR_API_TOKEN"
Only then is it actually processed.
What's not built yet
Being upfront about the current limits, rather than leaving you to discover them the hard way:
- No email verification on new signups yet, and no admin approval step — anyone can create an account, though they can't do anything beyond browsing until they subscribe.
- No web interface for managing products, placements, or campaigns yet — the API above is the only way, for now.
- No automated invalid-traffic detection. An unusual pattern of clicks on one campaign is something you'd need to notice yourself and act on with a refund.
- No moderation queue — a campaign goes live the moment it's created; review is on you.
- No listing endpoint for individual ad events, which the refund flow above needs the ID from.
- Outgoing email isn't configured yet, so password-reset and invite emails won't currently arrive.