Thread Docs

Getting started

From zero to your first classified email in about ten minutes.

This walks you from a fresh account to reading a real, classified message through the gateway. You'll register an app, connect a mailbox, and make your first authenticated call.

What you need

A Thread developer account and Node 18+. Everything below uses the official SDK, @jointhread/sdk.

Register an app

In the developer console, choose Register app. You'll get four credentials — copy them somewhere safe, because the secrets are shown only once:

CredentialUsed forVisibility
clientIdIdentifies your app in the Connect flowPublic
clientSecretExchanging connect codes (server-side)Secret — shown once
apiKeyCalling the gateway data planeSecret — shown once
webhookSecretVerifying webhook signaturesSecret — shown once

You can rotate any secret later from the app's detail page.

Install the SDK

npm install @jointhread/sdk

Add a Connect button

Your user authorizes a scoped grant on Thread's hosted consent page. From the browser:

connect-button.ts
import { openThreadConnect } from '@jointhread/sdk';

button.onclick = () =>
  openThreadConnect({
    baseUrl: 'https://app.jointhread.com', // Thread's hosted consent
    clientId: process.env.THREAD_CLIENT_ID!, // from the console
    redirectUri: 'https://yourapp.com/thread/callback',
    scopes: ['financial'], // seeds the user's default filter
    state: csrfToken,
  });

Thread redirects the user back to your redirectUri?code=...&state=....

Exchange the code (server)

On your callback route, swap the one-time code for a stable accountId. This call uses your client secret, so it must run on your server.

callback.ts
import { exchangeConnectCode } from '@jointhread/sdk';

const { accountId, mailbox, scopes } = await exchangeConnectCode({
  baseUrl: 'https://api.jointhread.com',
  clientId: process.env.THREAD_CLIENT_ID!,
  clientSecret: process.env.THREAD_CLIENT_SECRET!,
  code: req.query.code,
});

// Store accountId against your user — it's how Thread addresses this mailbox.

Read message metadata

Use your API key with the ThreadClient. Address the mailbox by the accountId you just stored, and (in this phase) narrow by sender domain:

read.ts
import { ThreadClient } from '@jointhread/sdk';

const thread = new ThreadClient({
  apiKey: process.env.THREAD_API_KEY!,
  baseUrl: 'https://gw.jointhread.com',
});

const { messages } = await thread.messages.list({
  accountId,
  fromDomain: 'amazon.com',
});

console.log(messages[0]?.subject, messages[0]?.labels);

You get back metadata and Thread's classification labels — never the raw body.

Next