Skip to main content

Grant TV access from your own website (partner API)

If your own site already authenticates viewers, it can unlock their television directly. No code typed, no viewer identity shared with Tappla, and your subscriptions and customer data stay on your side.

Written by Robert Blessing

If your website already knows who your members are, it can unlock their television directly. Your viewer signs in where they always sign in, confirms the code on their screen, and the TV opens. They never type an access code, and their identity stays on your side.

This is for organizations that want to keep subscriptions, customer data and billing outside their app vendor. If you would rather not integrate anything, access codes do the same job with no engineering at all.

This API is in beta. It is live and you can build against it today. Two things follow from beta: the apps that enforce locking are still rolling out, and the contract itself can still move if it does not fit you. Both are covered below.

What crosses the boundary

Deliberately thin, in both directions.

We receive

We do not receive

A code that is on a television right now

Who the viewer is

An opaque reference you choose for that viewer

What they paid, or whether they did

An optional list of tags

Their email, name or address

What we store is a device, a token hash and those tags. The reference is yours and means nothing to us: your-user-8842, a UUID, a hash. Pick something you can look up on your side and that does not leak anything on ours. It appears in a URL path, so keep it opaque and under 255 characters.

The flow

  1. The television asks us for a link and shows the short code it gets back.

  2. Your viewer, signed in on your site, enters that code on a page you host.

  3. Your server calls POST /api/partner/claim with the code and your reference for that viewer.

  4. The television picks it up on its next poll, within about three seconds.

Your page replaces the Tappla activation page. You never see the television's secret, and the television never sees your user.

Which apps this works on

The API is the same on every platform. What differs is whether the app on the television acts on the lock, because that is enforced by the app rather than by us.

Platform

Where it stands

Fire TV

Enforces locking and completes the handshake in the current app.

Roku

Arrives with the new SDK app, which we are rolling out now.

Apple TV

Arrives with the new SDK app, which we are rolling out now.

Until an app is rebuilt on the new SDK, a locked row still shows and still plays there. Nothing you build against this API has to change when that happens; it is a rebuild on our side, not a new contract. Ask [email protected] where your apps stand before you rely on the lock in production.

Authentication

Authorization: Bearer tpk_...

One key per integration, hashed at rest, shown once when it is created. The key identifies your application by itself, which is why no endpoint takes an app id. Ask us at [email protected] for a key and give it a label, so that two live keys are still tellable apart when you rotate. Rotation is mint-then-revoke.

A missing header, a malformed one, a revoked key and a lapsed subscription all return the same 401 with the same body.

Treat the key like any other server credential: keep it on your backend, never in a browser or a mobile app, and tell us at [email protected] if one is exposed so we can revoke it. A key can only ever touch your own account.

POST /api/partner/claim

Attaches the television showing code to a viewer you have already authenticated.

{
"code": "K7M2QP",
"subjectRef": "your-user-8842",
"tags": ["premium"],
"expiresAt": "2026-09-18T00:00:00Z",
"maxDevices": 3
}

Only code is required. No tags is a complete one-tier grant: locked content with no required tags plays on any linked device. No expiresAt means it does not expire, which is the shape of a subscription tier; a rental is the case that has to say so. No maxDevices means unlimited.

A successful call returns the entitlement as it now stands:

{
"status": "claimed",
"subjectRef": "your-user-8842",
"tags": ["premium"],
"active": true,
"expiresAt": null,
"maxDevices": 3,
"devices": 1
}

Idempotent on subjectRef. Calling again for the same viewer adds their second television, updates tags after an upgrade, or pushes the expiry out after a renewal. It does not create a second entitlement, which would make a later revoke look like it worked while the other one kept playing. Calling after a revoke lets the viewer back in and keeps the televisions already attached.

Every call states the entitlement in full, so an omitted field is cleared rather than kept. Send tags again when you add a second television, or that viewer ends up with none. It works this way because you derive all of it from your own subscription record on every call; the other rule would mean a downgrade that forgot to send tags quietly left someone on the tier they stopped paying for. Changes reach every television on that entitlement at its next poll.

You may omit subjectRef if you will not name the viewer even opaquely. That grants a fresh entitlement each time and leaves a later revoke nothing to aim at, which is the trade rather than a bug.

Limits. subjectRef and each tag are 255 characters at most, and an entitlement holds at most 50 tags. Anything past that is a 422 naming the field.

Status

Meaning

200

Linked. The television picks it up within about three seconds.

404 link_not_found

No pending code of that value in your account. A code belonging to someone else returns this too.

410 link_expired

The code was real and the viewer was too slow. Tell them to read the fresh code off the screen, which is a different instruction from "that never existed".

409 device_limit_reached

maxDevices reached. The device already holding the entitlement is excluded, so re-linking after a factory reset does not trip it.

422

code_required, invalid_subject_ref, invalid_tags, invalid_expires_at, invalid_max_devices, or invalid_entitlement with a detail field naming what was wrong.

GET /api/partner/entitlements/:subjectRef

What this viewer holds, including how many televisions are on it. 404 not_found if unknown, including when the reference belongs to another account.

DELETE /api/partner/entitlements/:subjectRef

Switches the viewer off. Takes effect at the next poll and the next launch, on every television they linked. 404 not_found if unknown.

Why you push to us rather than us calling you

The obvious request is the other one, so it is worth saying why it is this way round.

If we called your API on every playback check, a viewer would lose their television whenever you had an outage, and your service would sit in the path of every launch of every app. Instead, entitlements are re-read on every poll and every launch rather than trusted from claim time, so a revoke propagates on its own the moment it reaches us. Nothing to notify, nothing to touch on the hardware.

The trade: revocation is as fresh as your last call to us, not as fresh as your own database. For a lapsed subscription that gap is a webhook away. If you need per-play authorisation against live state, this shape is the wrong one and we should talk before you build against it.

Tags and tiers

An item in your feed can carry required tags, a device holds tags, and the app matches the two. Tags rather than item ids, so the check stays the same size as your catalog grows and you never have to know what is in the feed today.

Locked content with no required tags plays on any linked device. That is the one-tier model, "you need an account, any account", and it is what the dashboard produces on its own. Multiple tiers are available here through the API.

Current limits

  1. Keys are issued by us, not from the dashboard. Ask support and we will mint one.

  2. No webhook from us to you. Nothing tells your system that a television linked. Poll the entitlements endpoint if you need to know.

  3. No bulk endpoint. One viewer per call. If you need to migrate many at once, talk to us rather than looping.

  4. Roku and Apple TV enforcement is still rolling out. See Which apps this works on above.

The contract is young and no customer is locked into it yet, so if something about it does not fit how your system works, that is worth a conversation rather than a workaround. Write to [email protected].

Related

Did this answer your question?