live · mainnetoc · docs
specs · api · guides
docs / integrations

OC Me · Integrations

OC sits as a peer next to your existing OAuth providers. A first-time user picking OC has a federation-custodied bitcoin wallet provisioned silently — no seed phrase, no key handling, no "what is a sat" conversation. Sat-earning starts on first session.

See it live first

Before you read another paragraph, me-demo.ochk.io is a real OC integration we built ourselves — a fictional newsletter site (Lumen Notes), styled deliberately not-orangecheck. The signin button there opens the OC popup. Sign in once and you'll see the whole loop end-to-end. Source at github.com/orangecheck/oc-me-demo-web. ~280 lines of meaningful integration code, including the /api/auth/me wrapper and the popup-signin handler.

OAuth-peer pattern

import { signInWithOc } from '@orangecheck/me-client/popup';
import { signIn } from 'next-auth/react';
import { useState } from 'react';

export function SignInOptions() {
    const [busy, setBusy] = useState(false);
    async function onOc() {
        setBusy(true);
        const result = await signInWithOc();
        setBusy(false);
        if (result) {
            localStorage.setItem('oc-token', result.token);
            location.assign('/dashboard');
        }
    }
    return (
        <div className="auth-options">
            <button onClick={() => signIn('google')}>
                continue with google
            </button>
            <button onClick={() => signIn('apple')}>continue with apple</button>
            <button onClick={() => signIn('email')}>email magic link</button>
            <button onClick={onOc} disabled={busy}>
                {busy ? 'opening…' : 'sign in with oc'}
            </button>
        </div>
    );
}
What your user seesWhat your user does NOT see
a button next to google / applea seed phrase
one redirect to me.ochk.ioa wallet creation flow
signed in on your sitea "buy bitcoin" CTA
(eventually) a growing sat balanceany crypto vocabulary at all

When do they find out? When they want to. me.ochk.io/me shows their balance, me.ochk.io/me/wallet shows receive/send/withdraw, me.ochk.io/me/graduate offers self-custody. None of this is in the OAuth path. None of it surfaces unless the user explicitly visits.

Sample integrator archetypes

The configurator at me.ochk.io/integrate ships with six representative sample configurations. Different unit economics produce different choices — there's no "right" config OC sets, just the math.

ArchetypeDomainAccount creationSessionPaymentUser share
Lightning fintechbreez.example2,100 sats80 sats0.50%70%
Cashback-heavyfold.example1,600 sats60 sats0.95%78%
Lightning-native socialdamus.example40 sats50%
Merchant SaaS · KYC-requiredzaprite.example5,300 sats75 sats0.85%55–65%
Community federationfedi.example850 sats50 sats78%
Creator platformcreator.example1,100 sats35 sats0.65%60–70%

The config schema is open and self-served — see /me/sdk for the full shape and /developer/config for the inline editor.

Cross-product flows · me + fleet

A consumer using me.ochk.io may sign into a SaaS that runs on fleet.ochk.io for managed agent infrastructure. The envelopes are the same primitive (oc-attest, oc-stamp, oc-agent) — the two products are two integration surfaces over identical contracts.

FlowSurface
User signs into a SaaS using OC buttonme.ochk.io issues the session · fleet.ochk.io receives it via the family cookie / JWT
Agent takes a stamped actionfleet.ochk.io publishes the envelope · me.ochk.io credits sats per the SaaS's pricing
User revokes a delegationfleet.ochk.io publishes oc-agent-rev:[id] · the verifier drops further envelopes

Agent delegation lifecycle (issuance, revocation, list, audit) lives on fleet.ochk.io — that's the enterprise managed Agent product. me.ochk.io handles the wallet, identity, and billing substrate underneath. See fleet.ochk.io integrations docs for the operator-side view.

Errors and edge cases

ErrorMeaningFix
IntegratorPriceConfig invalid (422)Validation failed server-side.Run oc.config.validate(cfg) locally first; the response includes details: [{ subtype, message }].
signature does not match from oc.webhook.verifyEither you parsed the body before verifying, or you're verifying against a stale JWK.Use raw body bytes; re-fetch JWKS via oc.webhook.fetchJwks().
rate_limit_exceeded (429)You exceeded a per-IP bucket.Honor Retry-After; back off exponentially.
domain not verified (403)Your project_key fired in live mode but verification.state !== 'verified'.Run domain verification at me.ochk.io/me/projects/<key> (DNS TXT or meta tag), then retry.

Self-host considerations

me.ochk.io is one implementation of the canonical OC primitives. Anyone can run their own me-equivalent against the same envelope contracts — that's the product strategy. If you're considering self-hosting, the contracts to honor are at:

  • oc-attest-protocol/SPEC.md (identity)
  • oc-attest-protocol/FEDERATION-CUSTODY.md (v1.2-draft-1 federation custody)
  • oc-stamp-protocol/SPEC.md (anchored receipts)
  • oc-agent-protocol/SPEC.md + FEDERATION.md (delegations)
  • oc-lock-protocol/SPEC.md (encrypted DMs)

The hosted me.ochk.io substrate is a convenience, not a moat. Charter commitment 04 keeps every reference site free and self-hostable forever.