Getting started

Quickstart

From nothing to a first answer on your own phone in about twenty minutes.

How the pieces fit

ContextKit is a custodian of location, not a library that runs on your servers. A person installs the ContextKit app on their iPhone and signs in. From then on their phone uploads its location to ContextKit, and ContextKit holds it. Your product never receives coordinates: it asks ContextKit a question — "are they inside this zone?", "which of their places are they at?" — and gets an answer, or a webhook when an answer changes.

Three things therefore have to exist before you can ask anything:

  1. A phone that reports. The ContextKit app for iPhone, signed in. For development that is your own phone; for your users it is theirs (see Your users need the app).
  2. An app registered in the developer portal at contextkit.com, with the scopes it may ask for and the redirect URI it connects through.
  3. Your backend, holding the client secret and the per-user tokens, and making the calls — with the Node SDK or plain HTTPS.

1. Enrol your own phone

Install the ContextKit app, sign in with the account you use for the developer portal, and allow location "Always". Walk somewhere, or wait: a moving phone uploads a point every few minutes, a still phone uploads nothing until it moves again. The Test devices page in the portal shows the last upload from each phone, which is how you know data is arriving.

Until at least one point has landed, every answer is unknown — correct, and indistinguishable from a broken integration if you do not expect it.

2. Register an app

Sign in at contextkit.com and create an app on the Apps page. It starts in sandbox: instant, no review, and connectable only by you, against your own phone. That is enough to build and test everything on this site.

On the app's Credentials tab, register the redirect URI your backend will handle. Saving it mints the client secret, shown once. On the Scopes tab, the app lists every scope it may ever request; a user can grant fewer.

The Playground in the portal asks a live question against your phone with a short-lived token, and shows the exact response body — the quickest way to see what an answer looks like before writing any code.

3. Connect and ask

pnpm add @tinbee/contextkit-sdk
import { ContextKit, generateCodeVerifier, generateState } from "@tinbee/contextkit-sdk";

const ck = new ContextKit({
  clientId: process.env.CONTEXTKIT_CLIENT_ID!,
  clientSecret: process.env.CONTEXTKIT_CLIENT_SECRET!,
});

const redirectUri = "https://api.example.com/contextkit/callback";

// Send the user to consent. Keep state and verifier in THEIR session: the
// callback needs both, and a callback whose state does not match is refused.
const state = generateState();
const codeVerifier = generateCodeVerifier();
session.contextkit = { state, codeVerifier };
redirect(
  ck.authorizeUrl({
    redirectUri,
    scopes: ["location.verify.zone", "location.place.current"],
    state,
    codeVerifier,
    externalUserId: user.id,
  }),
);

// On the callback: check state, exchange the code, persist the token set per user.
if (query.state !== session.contextkit.state) throw new Error("state mismatch");
const tokens = await ck.exchangeCode({
  code: query.code,
  codeVerifier: session.contextkit.codeVerifier,
  redirectUri,
});

// Ask.
const ckUser = ck.forUser(tokens, { onTokens: (next) => save(user.id, next) });
const answer = await ckUser.answers.verifyZone({
  lat: 48.3537,
  lon: 11.7861,
  radiusM: 500,
  label: "Munich Airport arrivals",
});
// answer.state: "inside" | "outside" | "unknown"

The Node SDK page covers every call. Authentication covers the same flow as raw HTTP, for any other language.

Your users need the app

A person can only be asked about if their phone reports to ContextKit, so every user of your product needs the ContextKit app, signed in with their own account. The consent screen handles the ask: a user who arrives there without an enrolled phone is told to install the app and sign in with the same account, and can approve your app either way.

This is the same shape as a camera pairing with its maker's phone app for location: one install, and every ContextKit-connected product the person uses afterwards enrols in a tap. Users see every connected app, what each one asked, and a Disconnect button, in one place.

Going to production

Sandbox apps can be connected only by their developer. Going live is a review of the app, run from its "Go live" tab in the portal:

  1. Complete your developer profile once, on the Account page: legal entity, website, privacy policy and terms URLs, a security contact, and acceptance of the Data Processing Agreement. Every review reuses it.
  2. Answer the questionnaire on the app's Go live tab — what the app does in a user's words, who the users are, why each scope and what breaks without it, what happens to answers on your side, how a user revokes from inside your product, and whether you ship a web app with the companion app or a native app embedding the package. Drafts save as you type.
  3. Attach documents if you have them: privacy policy, DPA, consent screenshots. PDF, PNG or JPG, 10 MB each.
  4. Submit. We check that the privacy policy is reachable on your own domain, read the answers, and either approve, ask for changes with a note, or decline with a reason. You get an email either way, and the tab shows the note.
  5. Press Go live. Approval does not flip the app by itself; you do, when you are ready. From then on any ContextKit account can connect it, and its request and question ceilings scale with its connections (see Errors and limits).

Adding a scope to a live app is the same review for that scope only; the app stays live on the scopes it already has.

By creating an app you accept the Developer Terms and the Acceptable Use Policy. All of them, with the Privacy Policy your users see, are at contextkit.com/legal.

Previous
Overview