oc · me
§ integrate · quickstart

Eight steps. About five minutes to first envelope; ten more to harden for production.

From new project to first billable envelope, then a production-hardening HMAC step on top — every step has the actual code sample. Mark steps done as you go; progress persists locally, no account needed to read this page.

§ progress
0 / 8 · 0%
  1. [01]

    create your project

    sign in at me.ochk.io, then run the three-step wizard at /me/projects/new. your OC identity IS your integrator account — no separate developer signup. you get a project_key + a public JWK URL. ~60 seconds.

    # /me/projects/new
    display_name: YourCompany
    domain: yourcompany.com
    mode: test
    → project_key: pk_test_a4f9k2x...
    open /me/projects/new
  2. [02]

    verify your domain

    until verified, your project_key cannot fire live envelopes against your domain. add a DNS TXT record (or a meta tag on your homepage) and click "verify now" — backend tries DNS first, falls back to the meta tag fetch. test mode is unrestricted; this gate applies to live mode only.

    # DNS TXT at yourcompany.com
    oc-verify=<token shown on /me/projects/[id]>
    
    # OR meta tag in <head>
    <meta name="oc-domain-verify" content="<token>" />
    see the verify card
  3. [03]

    install the SDK

    one npm package, three subpath entry points. /server has the framework adapters (no env vars, no JWK handling). /popup has the signin orchestrator. The main package re-exports the React provider + types from auth-client.

    yarn add @orangecheck/me-client @orangecheck/auth-client
  4. [04]

    drop the popup signin

    add a button. inside the click handler, call signInWithOc(). a 480x720 me.ochk.io popup opens, user signs in (email-OTP or BIP-322), popup postMessages the session token back, closes itself. same shape Google / GitHub use; users recognize it.

    import { signInWithOc } from '@orangecheck/me-client/popup';
    
    button.addEventListener('click', async () => {
      const result = await signInWithOc();
      if (!result) return; // user cancelled
      localStorage.setItem('oc-token', result.token);
      location.assign('/dashboard');
    });
  5. [05]

    verify the session server-side

    wrap your protected route with withOcAuth (Next.js Pages), ocAuthExpress (Express), or ocAuthHono (Hono). the wrapper handles JWKS retrieval + caching internally — you never see /.well-known/jwks.json or an env var. cookie auth + Bearer-token auth handled identically.

    // pages/api/auth/me.ts
    import { withOcAuth } from '@orangecheck/me-client/server';
    
    export default withOcAuth(async (req, res) => {
      if (!req.ocSession) return res.status(401).json({ ok: false });
      res.status(200).json({ address: req.ocSession.did_oc });
    });
    see all stack snippets
  6. [06]

    smoke-test the loop

    fire a real envelope under your project_key from /me/projects/[id] (smoke test panel). see it land in the live event stream within seconds. test webhook delivery with one click before you wire your backend. exact same pipeline as production — signed, co-signed, OTS-anchored, fanned out.

    # /me/projects/[id]
    [ fire test envelope → ]
      subtype: session_creation
      ↓
      envelope id: oc-me-tx7m4f9k
      webhooks_fired: 0 (none registered yet)
      → live in /verify/[id]
    see the user demo end-to-end
  7. [07]

    flip to live

    set per-event prices in the config editor. choose how much of each fee streams to your user vs your rebate. domain verified + project in live mode = envelopes ship. paired comparisons against your actual stack come back in a business day if you want one.

    # /me/projects/[id] · config
    mode: live
    session_creation:    60 sats · user_share 65%
    payment_authorization: 0.75% of amount · user_share 65%
    request a paired comparison
  8. [08]

    turn on request-signing (optional · production hardening)

    attach a short HMAC over every server-to-OC request body. reveal a 256-bit secret in /me/projects/[id]/keys, sign on your backend, flip the enforcement toggle. start in advisory mode (server logs missing signatures but accepts them) until your fleet is signing cleanly, then enforce. once enforced, unsigned requests get 401 — defense against stolen project_key replay.

    // node · sign every /api/integrator/event POST
    import { createHmac } from 'node:crypto';
    const ts = Math.floor(Date.now() / 1000);
    const sig = createHmac('sha256', process.env.OC_SIGNING_SECRET)
      .update(`${ts}.${rawBody}`)
      .digest('hex');
    headers['X-OC-Signature'] = `t=${ts},v1=${sig}`;
    reveal/rotate the secret

next, deeper

The quickstart gets you to first envelope. After that: /why#integrators has the full pitch + comparison table, /integrate/sandbox runs your config against a representative one-month event mix, and docs.ochk.io/me/sdk documents every export, type signature, and code sample.

Just want your users to have an OrangeCheck identity — not the me.ochk.io billable-events product? That is a separate, simpler integration: docs.ochk.io/integration covers letting OrangeCheck be your sign-in, or adding a did:oc to the login you already run.