Getting started

Getting started

From nothing to a working “Connect with Geena” button, in order. Everything here happens once, at setup time; the demo apps are a complete worked example of the result.

1. Create your organization

Sign in at dashboard.test.geena.eu (email + one-time code — the account is created on first login) and create your organization. The organization is the owner of everything that follows: manifests, app credentials, and the connections users grant.

2. Register your app

In the dashboard, as an organization admin: Organization → Apps → Register app. You choose the client_id (the slug), a display name for the consent screen, an optional privacy-policy URL, and your exact redirect origins (scheme + host + port, e.g. https://app.example.com — the redirect_uri must match one of them origin-exactly). The client_secret is shown once — store it in your backend’s secret store; it never belongs in browser code. Edit the profile, rotate the secret or disable the app from the same page; a disabled app stays listed as history and never comes back.

Two ceilings sit above the app:

  • Organization access — a switch on the app. Every app gets the identity-only login (profile, offline_access); turn organization access on if your back office will read kept copies and decide proposals through the Organization API. It adds the organization scope to what the app may ask for — nothing else, and ordinary connections never need it. Turning it off later ends the app’s live sessions.
  • your organization’s capability, set by the Geena team: which schema targets and verbs (fill/edit/keep) your manifests may ask for. Email support@geena.eu with what you plan to use — a manifest a user cannot accept helps nobody.

3. Author and publish a manifest

In the dashboard, Manifests → New. A manifest is the versioned shape of your ask:

  • Slots — each one thing you ask for: a built-in schema (PersonFullName, PersonAddress, PersonIdentityDocument, …) or supporting files, with the verbs you need beyond reading (fill to collect in-app, edit to push updates, keep to hold a revocation-surviving copy). A slot is single by default — one standing answer, a later fill replaces it — or multiple when answers should accrue (“all your addresses”).
  • Adoption policy on every keep slot — MANUAL: your team, or your back office, keeps a copy explicitly; AUTO: Geena keeps the first version and every later one as soon as they exist, whenever your organization’s key is warm (a member is signed in), and queues the copy until then.
  • Groups — presentation sections, mirrored back to you in /status.
  • Subjects — declare them if you ask about parties beyond the account holder. A subject is typed: PERSON with a kinship relation (“each child you cover”), or LEGAL_ENTITY for a company the user represents (“the investing company”). Slots that carry a subject are answered from that party’s vault — see Subjects: relatives & companies. Company subjects take the LegalEntity* schemas and ENTITY_FILES for evidence; person subjects take the Person* schemas and PERSONAL_FILES.
  • Terms — legal basis, purpose, retention; rendered verbatim on the consent screen.
  • Initiation — who may start a connection: your organization, the recipient (the button lane), or both.

Publish the manifest and copy its manifest id from the card. Editing later creates a new version — existing connections stay pinned to the version the user accepted; re-consent is what widens them.

The manifest card also offers Export JSON (and the list page Import JSON) — author once, move the same shape between environments, keep it in your repo. The file is the same input the dashboard sends; a compact example with a company subject:

{
  "name": "Investor onboarding",
  "initiation": "BOTH",
  "groups": [
    { "id": "identity", "label": "Who you are", "order": 1 },
    { "id": "company", "label": "Investing company", "order": 2 }
  ],
  "subjects": [
    { "id": "investing-company", "type": "LEGAL_ENTITY",
      "label": "Investing company (only if you invest through one)", "repeat": false }
  ],
  "slots": [
    { "label": "Full name", "group": "identity", "kind": "SCHEMA", "target": "PersonFullName",
      "verbs": ["FILL", "EDIT", "KEEP"], "adoption": "AUTO" },
    { "label": "Addresses", "group": "identity", "kind": "SCHEMA", "target": "PersonAddress",
      "multiple": true, "verbs": ["FILL", "KEEP"], "adoption": "MANUAL" },
    { "label": "Company details", "group": "company", "subject": "investing-company",
      "kind": "SCHEMA", "target": "LegalEntity", "verbs": ["FILL", "EDIT", "KEEP"], "adoption": "AUTO" },
    { "label": "Company evidence", "group": "company", "subject": "investing-company",
      "kind": "ENTITY_FILES", "multiple": true, "verbs": ["FILL", "KEEP"], "adoption": "MANUAL" }
  ],
  "terms": {
    "legalBasis": "LEGAL_OBLIGATION", "purpose": "KYC",
    "retentionDays": 1825, "retentionAction": "ARCHIVE",
    "rightToErasure": false, "rightToRectification": true, "allowDownload": false,
    "privacyPolicyUrl": "https://app.example.com/privacy"
  }
}

The file spells its enums in upper case (SCHEMA, PERSONAL_FILES, ENTITY_FILES, FILL, AUTO, PERSON, LEGAL_ENTITY, CHILD, …); the REST planes speak the same vocabulary in lower case (schema, fill, person, …). The demo manifests are importable examples.

4. Configure your app

Three values, all deployment configuration:

GEENA_API_URL   = https://api.test.geena.eu
CLIENT_ID       = <from registration>        # public
CLIENT_SECRET   = <from registration>        # backend only
MANIFEST_ID     = <from the published card>  # public — it travels in the authorize URL

Different products with different asks are simply different manifest ids on different buttons.

5. Add the button

Implement the connect ceremony: popup to /oauth/authorize with PKCE and your manifest_id, a landing page on your registered origin, a server-side code exchange. The exchange hands you tokens and the request_id — store it; it is the address of everything else.

6. Verify the loop

curl -H "Authorization: Bearer <access token>" \
  https://api.test.geena.eu/partner/v1/requests/<request_id>/status

You should see your manifest’s groups and slots with their grant status. From here: read what was granted, fill what is pending in-app, and keep the recipes open — they cover the common jobs end-to-end.

7. Connect your back office

A member of your organization signs in through the same ceremony with scope=organization and no manifest — see Organization access. The token that comes back opens the Organization API: your requests, the copies you kept, the files you hold, and the update proposals waiting for a decision — the same view the dashboard gives your team, for your own systems.