<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Partner API :: Geena API</title>
    <link>https://docs.test.geena.eu/partner-api/index.html</link>
    <description>Partner API Everything your app needs to hold a connection with a Geena user: a “Connect with Geena” popup that logs the user in and captures consent in one screen, then a small REST plane (/partner/v1) for reading, filling, and maintaining the data the user granted you.&#xA;The model in six sentences Your organization publishes a manifest in the Geena dashboard — the versioned shape of what you ask for: slots (a passport, a proof-of-address document, supporting files, …), presentation groups, and terms. When a user consents, Geena mints a connection (internally: an accepted request) pinning that manifest version. The connection id — request_id — is the address of everything else in this API. Data rights come from per-slot grants the user controls, never from OAuth scopes: your tokens carry identity only, and every call re-checks the grant behind it. Every act on the plane — reading a value, listing candidates, attaching, creating, writing, deleting — is receipted to the user’s timeline with your app’s client id. Design your integration expecting the user to see it. A manifest can also ask about people beyond the account holder — subjects (“each child you cover”): the user answers those in your app from their family-member vaults, addressed only by pairwise aliases. What the user did not grant is invisible: an ungranted, foreign, malformed or nonexistent id all answer the same 404 not_found, and a pending slot is indistinguishable from “the user has no such data” (the oracle rule). Section contents Getting started — organization, app registration, manifest authoring and publishing, wiring the ids into your app. Connect with Geena — the popup ceremony, PKCE, the code exchange, token lifecycle. Connections &amp; status — discovering your connections and driving your UI from per-slot status. Reading &amp; writing data — serving granted slots, file content, delegated writes and deletes. Filling slots in-app — the native picker: candidates, attach, slot-bound create. Relatives &amp; subjects — manifests about the family: person candidates, adding a child, filling per person. Recipes — copy-paste sequences for the common jobs: fill, update, relatives, files, login, revocation. Errors &amp; step-up — the error envelope, code table, sealed vaults and the hosted verification hand-off. OpenAPI specification — the machine-readable contract for /partner/v1. Base URLs (test environment) What URL API (authorize, token, plane) https://api.test.geena.eu Hosted pages (consent, verify) https://dashboard.test.geena.eu All /partner/v1 calls take Authorization: Bearer &lt;access token&gt;.</description>
    <generator>Hugo</generator>
    <language>en</language>
    <atom:link href="https://docs.test.geena.eu/partner-api/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Getting started</title>
      <link>https://docs.test.geena.eu/partner-api/getting-started/index.html</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://docs.test.geena.eu/partner-api/getting-started/index.html</guid>
      <description>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.&#xA;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.</description>
    </item>
    <item>
      <title>Connect with Geena</title>
      <link>https://docs.test.geena.eu/partner-api/connect/index.html</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://docs.test.geena.eu/partner-api/connect/index.html</guid>
      <description>Connect with Geena One button in your app opens a popup on Geena’s origin; the user logs in (email + one-time code — first-time users are provisioned on the spot), sees one consent screen with your manifest’s asks and terms, and the popup closes. Your backend then exchanges a short-lived code for tokens and the connection’s request_id. Returning users with a live consent skip the screen entirely — the popup flashes and closes.</description>
    </item>
    <item>
      <title>Connections &amp; status</title>
      <link>https://docs.test.geena.eu/partner-api/connections/index.html</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://docs.test.geena.eu/partner-api/connections/index.html</guid>
      <description>Connections &amp; status List your connections GET /partner/v1/requests Authorization: Bearer &lt;access token&gt; Returns every active connection your organization holds with the token’s user — the recovery path when you did not store request_id at connect time. Pending invitations are never listed: before consent there is no connection.</description>
    </item>
    <item>
      <title>Reading &amp; writing data</title>
      <link>https://docs.test.geena.eu/partner-api/vault-data/index.html</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://docs.test.geena.eu/partner-api/vault-data/index.html</guid>
      <description>Reading &amp; writing data Slot kinds map to three record types: schema slots serve structured documents, id_document slots serve identification documents, personal_files slots serve files. Reading a granted item needs no verb — that is what a connection is; writing and deleting need the slot’s edit verb (visible in /status). Every operation below also requires a grant; a slot the user has not granted answers 404 not_found, indistinguishable from one that does not exist.</description>
    </item>
    <item>
      <title>Filling slots in-app</title>
      <link>https://docs.test.geena.eu/partner-api/fill/index.html</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://docs.test.geena.eu/partner-api/fill/index.html</guid>
      <description>Filling slots in-app A pending slot does not have to send the user to Geena: with the user present in your app you can render a native picker over what their vault already holds, let their tap grant an existing item, or create the asked-for value directly into their vault — granted to the slot in the same act.</description>
    </item>
    <item>
      <title>Relatives &amp; subjects</title>
      <link>https://docs.test.geena.eu/partner-api/relatives/index.html</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://docs.test.geena.eu/partner-api/relatives/index.html</guid>
      <description>Relatives &amp; subjects A manifest can ask about people beyond the account holder: each child you cover, your co-driver. Those asks are subjects — declared once in the manifest with a relation (child, partner, …) — and every slot that carries a subject id in /status asks about that role rather than about the user.&#xA;The user answers a subject with their family-member vaults: vaults they own and hold data in on a relative’s behalf. Your app never sees those vaults&#39; ids — every person is addressed by a pairwise alias, minted per connection, meaningless to any other organization.</description>
    </item>
    <item>
      <title>Errors &amp; step-up</title>
      <link>https://docs.test.geena.eu/partner-api/errors/index.html</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://docs.test.geena.eu/partner-api/errors/index.html</guid>
      <description>Errors &amp; step-up The error envelope Plane errors are JSON with a stable machine-readable code:&#xA;{ &#34;error&#34;: &#34;not_found&#34;, &#34;message&#34;: &#34;no such item&#34; } HTTP error Meaning 400 invalid_body Missing/malformed body (e.g. no data object, no file part) 400 invalid_document Payload fails the schema it is validated against 400 unsupported_item Operation not defined for the slot’s kind (e.g. create on id_document) 401 unauthenticated No valid caller behind the token 403 partner_token_required A first-party (non-partner) token was presented 403 unknown_client The token’s client is no longer registered 403 organization_suspended Your owning organization is suspended 403 connection_inactive The connection is revoked, withdrawn, or expired 403 verb_not_granted The slot does not carry the verb this operation needs 403 delete_refused The platform protects this document from deletion 404 not_found Ungranted, foreign, malformed, or nonexistent — deliberately one answer 409 ambiguous_item The (kind, target) pair matches several slots / records — use slot ids 423 sealed The user’s vault is sealed; see step-up below 500 server_error Transient server failure — safe to retry Info Read 404 as “nothing for you here”, never as “does not exist.” The same answer covers an item the user declined to share, an id from another user, and an id that was never real. Probing teaches nothing — by design.</description>
    </item>
    <item>
      <title>Recipes</title>
      <link>https://docs.test.geena.eu/partner-api/recipes/index.html</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://docs.test.geena.eu/partner-api/recipes/index.html</guid>
      <description>Recipes Copy-paste sequences for the common jobs. Everything below assumes an active connection and a bearer token:&#xA;API=https://api.test.geena.eu/partner/v1 REQ=&lt;request_id&gt; # from the token exchange, or GET $API/requests AUTH=&#39;Authorization: Bearer &lt;access token&gt;&#39; All of these flows are implemented end-to-end in the public demo apps — github.com/Identa-io/demo is the reference integration.&#xA;Read everything the user granted curl -H &#34;$AUTH&#34; $API/requests/$REQ/status # for each item with status=granted: curl -H &#34;$AUTH&#34; $API/requests/$REQ/slots/&lt;slotId&gt; Serve-on-read means you always get the current version — if the user updates their address in Geena, your next read has it. Do not cache what you were not granted keep for.</description>
    </item>
    <item>
      <title>OpenAPI specification</title>
      <link>https://docs.test.geena.eu/partner-api/openapi/index.html</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://docs.test.geena.eu/partner-api/openapi/index.html</guid>
      <description>OpenAPI specification The /partner/v1 plane is defined by an OpenAPI 3.0 document — the same file the Geena backend generates its routing from, so the published contract cannot drift from the implementation.&#xA;Download partner-v1.yaml&#xA;curl -sO https://docs.test.geena.eu/openapi/partner-v1.yaml Use it to generate a typed client in your stack (openapi-generator, oapi-codegen, openapi-typescript, …) or to import the collection into an API tool. Two conventions worth knowing when reading it:</description>
    </item>
  </channel>
</rss>