Staff sign in
Sign in with the email and password you set when accepting your Idunox invitation. A one-time code will be sent to your email on every sign-in.
A tenant is one customer or lab organization — the isolation boundary for API keys, pack entitlements, and all submission data. Use Create tenant to register a new organization. See Glossary → Tenant.
A credential is an API key tied to one tenant. Partners send it as X-Api-Key on api-test.idunox.com. See Glossary → Credential.
Partner portal — primary onboarding
Select a tenant above. Invitations are scoped to that tenant only — the invite link includes the tenant id.
Default path: send an invitation so the partner’s team signs in at partner-test.idunox.com/management/api-keys, sets their password, and creates and rotates API keys themselves. You do not need to handle plaintext secrets — the portal shows each key once, same as staff issuance.
| Name | Status | Last login |
|---|
Staff-issued API keys — backup only
Use Issue API key (backup) only when the partner cannot use the portal — e.g. invitation email failed, emergency unblock, or internal lab testing. Prefer resending the invitation first. Revoke and rotate still apply to keys created here or in the portal.
| Name | Prefix | Status | Expires | Created |
|---|
Staff admins who can sign in to this portal. You cannot delete/deactivate your own account or the last active admin. Tenant & submission deletions require a second admin to approve — keep at least two active.
| Name | Role | Status | Last login | Actions |
|---|
A submission is one lab result ingest request from a partner — scoped to the tenant derived from their API key, not from body fields alone. See Glossary → Submission. Rows with status REJECTED are POSTs rejected at intake (4xx) — sourced from the platform audit log, retained 90 days, with the error code in the Error column (hover for field-level reasons). 401/429 requests are not listed (see the partner-submission-failure runbook).
| Actions | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
Submission activity over the selected window — platform totals and per-tenant breakdown. See Glossary → Stats.
Load stats to see the dashboard.
Definitions for terms used across this staff portal and the andres-test partner API.
-
TenantOne customer or lab organization in the platform. Every API key, submission, result, and report artifact belongs to exactly one tenant. Tenants are the isolation boundary — partners never share data across tenants.
For partner-facing demos and docs verification, prefer one multi-pack customer tenant over many throwaway tenants. Do not merge tenants by editing JSON alone: credentials, subjects, submissions, jobs, results, artifacts, webhooks, idempotency keys, and audit logs are tenant-scoped records. -
Credential (API key)A secret issued to a tenant for machine-to-machine access. Stored as a hash + prefix only; the full secret is shown once at creation. Sent on each request as header X-Api-Key. Inherits the tenant’s pack entitlements.
-
SubmissionA single POST /v2/submissions ingest (current contract; /v1 is legacy) — partner blood markers and metadata entering the pipeline. The tenant is determined from the API key, not from partner IDs in the JSON body.
-
SlugA short, URL-safe identifier for a tenant (lowercase letters, numbers, hyphens). Used in key labels, scripts, and ops — e.g. health-yourself for Health Yourself.
-
PackA licensed Idunox product — Health Yourself, Pilot, or Care. A pack defines the marker intake scope (questionnaire + blood analytes), wellbeing outcomes, model bundle, report layout, and which partner documentation slices a tenant may view.
What you assign to a tenant: a pack (product license), stored in tenant.metadata.assignedPackIds. The platform may dual-write derived input panel IDs for legacy /v1 compatibility, but Staff UI and /v2 entitlement always use pack IDs (Care must not collapse to Pilot in the picker).
Where used: pack guard on POST /v2/submissions (403 PACK_NOT_ASSIGNED when the requested pack is not assigned); partner docs entitlement by pack ID; report template and model routing from the accepted pack snapshot. Customer tenants usually have one pack; lab tenants are for internal parity only. -
Panel IDStable machine identifier for a pack's input marker vocabulary, e.g. iduscore_health_yourself, iduscore_pilot. Care currently shares Pilot's input panel while remaining a distinct licensed pack ID (iduscore_care).
Where used: derived operational metadata dual-written beside assignedPackIds for the legacy /v1 path; never accepted as a public /v2 selector. Partners POST the /v2 wire with required packId plus Q/B guide ids — not panelId. -
Partner API versionThe partner API is a single documented contract — /v2; the URL path is the contract and no format headers are used. All andres-test partners integrate on /v2, and the Partner Portal API reference exposes pack selection only (there is no API-version selector). The runtime still retains the legacy /v1 wire (X-Idunox-Post-Format/X-Idunox-Get-Format) for the original production Rakesh integration; it is not offered to andres-test partners and is not selectable. Staff do not choose a tenant-level “Partner API contract” dropdown.
-
Report JSON versionDownloadable JSON report schema. On /v2 it is the normalized partner_report_json_v2, fixed server-side by packId (both HY packs emit it); staff do not choose it in Admin, and /v2 uses no format header. (The legacy /v1 path emits partner_report_json_v1 via X-Idunox-Get-Format.) The deployed v2 artifact is normalized: areas stay in wellbeingAreas[], all Q/B/D markers and marker-to-area ranks live in markers[].areaContributions[], and action ranks live in actions[].priority plus actions[].supportedAreas[].rankInArea.
-
Panel (marker profile)The full marker and model profile behind a pack: required blood marker guide ids (B### on partner wire), questionnaire Q001–Q037, inference model bundle, and report template. Docs often say “14-marker panel” or “13-marker panel” for the blood analyte list only — that list is part of the panel profile, not the whole product. Do not confuse with UI “tabs” in this portal (those are navigation panels).
Where used: validation presets (panel-blood-marker-presets.js), pack guard inference, parity fixtures, and pack-specific input-data guides. One pack ↔ one panel profile today; panel ID is the join key. -
Type (Customer vs Lab)Customer — real partner-style tenant (e.g. Health Yourself). Lab — internal andres-test tenant for gates and pack parity; not for production partner traffic.
-
PrefixThe first characters of an API key stored for support and UI display (e.g. idu_prod_sk_… for production keys, idu_dev_sk_… for dev). Lets staff identify a key without revealing the full secret.
-
Status (credential)Active — key accepts API calls. Revoked — key rejected immediately; use when rotating or deprovisioning access.
-
Partner submission IDThe partner’s own identifier for a submission (their idempotency / trace id). Distinct from our internal submission UUID.
-
Audit reasonRequired note on create, update, revoke, and pack changes — who did what and why. Stored in row metadata today (lastAdminChangeReason); a separate audit_logs table (model AuditLog) also exists, populated by the platform pipeline.
-
API base URLPartner integration endpoint for andres-test: https://api-test.idunox.com (version-neutral host; the current contract is /v2, e.g. /v2/submissions). Docs live in the partner portal at partner-test.idunox.com/docs.
-
StatsDashboard cards: platform totals (submissions, completion rate, active keys) plus per-tenant breakdown over the selected day window.
-
Staff sign-inEmail invitation → set password → sign in with email, password, and a mandatory one-time code sent by email on every login. Production URL: admin-test.idunox.com. Local dev: bash scripts/deploy/phase19_admin_ui_local_dev.sh → port 8791.
Staff guide for the andres-test Admin Portal. For term definitions see Glossary.
What this portal does
Idunox staff use this UI to onboard partners on the andres-test stack only: create tenants, assign biomarker packs, invite partners to the self-service portal, and monitor submissions. Partners integrate against api-test.idunox.com — not production Rakesh URLs.
Current API docs are pack driven: assign packs here, then partners select their pack in the Partner Portal API reference and integrate on /v2 (there is no API-version selector). Staff no longer choose tenant-level Partner API contract or Report JSON version dropdowns.
Current GCP stack status: partner traffic uses api-test.idunox.com, and the deployed V2 JSON artifact is the normalized partner_report_json_v2 model. Use the Partner Portal end-to-end examples and API reference to verify each pack/version combination.
How to open this UI
- Production (staff): https://admin-test.idunox.com — sign in with your invited staff account (email, password, and email OTP).
- Local dev (recommended): run bash scripts/deploy/phase19_admin_ui_local_dev.sh then open http://127.0.0.1:8791/ — serves latest disk HTML and proxies API to Cloud Run.
- Cloud Run proxy: run bash scripts/deploy/phase19_admin_ui_proxy.sh then open http://127.0.0.1:8787/ — serves UI bundled in the deployed image.
- Do not open admin-ui.html as a static file — API calls will fail with 404.
Tabs at a glance
- Tenants — list organizations; search, sort, and filter columns; Create tenant and a per-row edit (pencil) / delete (trash) action.
- Credentials — Send invitation (primary onboarding); staff Issue API key (backup), plus per-key rotate (circular-arrows icon) and delete (trash) actions.
- Submissions — load recent ingests (newest first by submission time), then sort by column, filter per column, or search all columns (client-side on loaded rows). Each row leads with the submission time (YYYY-MM-DD HH:MM:SS, local), tenant, and the API key used.
- Stats — dashboard: platform totals and per-tenant activity over N days.
- Glossary — definitions (tenant, pack, credential, …).
- Help — this guide, onboarding steps, troubleshooting.
Modal dialogs (common pattern)
Most write actions use a modal instead of a separate page — same pattern across tabs:
- Tenants → Create tenant — identity, packs (0–all), customer/lab type, audit reason.
- Tenants → row edit (pencil) — change name, slug, type, and assigned packs (0–all) + audit reason.
- Credentials → Send invitation — partner email invite (72h link; M365 when configured).
- Credentials → Issue API key (backup) — staff-issued secret (shown once); use only when portal path fails.
- Credentials → row rotate (circular arrows) / delete (trash) — audit reason required.
Tenant consolidation guidance
For partner-facing use, prefer a single customer tenant with all licensed packs assigned. Test and E2E tenants can be kept for gates, but should not be used as partner accounts once a canonical multi-pack tenant exists.
Consolidating existing tenants is a database migration: move or retire credentials, portal users, subjects, submissions, jobs, results, artifacts, webhooks, idempotency keys, and audit logs. Do not “centralize” by only changing assignedPanelIds.
Tenants & Submissions — search and filter
Both table tabs share the same pattern:
- Search all columns — matches visible text plus ids (tenant id on Tenants; internal submission id on Submissions).
- Filter row — type under each column header.
- Sort — click a column header; click again to reverse. Tenants default to name A→Z; Submissions default to newest first.
- Row count — shows filtered vs total when filters are active.
Submissions also has a tenant dropdown and Load to fetch from the API (max 200); sort/filter/search apply to loaded rows only.
Onboard a new customer tenant
-
1
Confirm the licensed pack
Default: assign every pack the customer has licensed (often one). Health Yourself → Health Yourself; add Pilot/Care when contracted.
-
2
Create the tenant
Open Tenants, click Create tenant (modal). Enter legal name and slug (e.g. acme-health). Pick the pack and Customer type. Audit reason is required.
-
3
Send a partner-portal invitation
Go to Credentials, select the tenant, click Send invitation. The partner receives email with a link to partner-test.idunox.com/management/api-keys, sets a password, then creates their own API keys in the portal.
-
4
Partner self-service keys (or staff backup)
Normally the partner creates keys in the portal — you never see the plaintext secret. If the portal is unavailable, use Issue API key (backup) on Credentials and deliver the one-time secret over a secure channel.
API base URL: https://api-test.idunox.com (version-neutral host; current contract /v2, e.g. POST /v2/submissions)
Partner portal: https://partner-test.idunox.com/management/api-keys
Partner docs: https://partner-test.idunox.com/docs -
5
Verify integration
Submit a canonical fixture with X-Api-Key only against api-test. On Submissions, click Load, then search or filter to find the ingest. Check Stats for totals. Submitting a packId the tenant is not assigned returns 403 PACK_NOT_ASSIGNED.
-
6
Optional: webhook
Configure callback URL via tenant metadata (API PATCH) or seed scripts. Andres-test default uses the internal webhook sink.
Partner portal invitations
- Primary path: Credentials → Send invitation — partner sets password via email link and creates keys at partner-test.idunox.com/management/api-keys.
- Resend: Pending invites show Resend invite in the portal users table (audit reason required).
- Email not sent: Configure M365 Graph via bash scripts/deploy/phase19_setup_partner_portal_email.sh, or copy the invite URL from the flash message and share securely.
- Backup keys: Issue API key (backup) only when the partner cannot use the portal.
Rotate or delete a key
- Rotate (circular-arrows icon): partner rotates in the portal (or staff uses backup issuance) → confirm traffic on the new key → delete the old key on Credentials (audit reason required).
- Delete (trash icon): Credentials tab → trash icon → confirm in the modal (audit reason required). The credential record is removed and the key stops working immediately.
- Two active keys per tenant during overlap is supported.
Troubleshooting
| Symptom | What to check |
|---|---|
| 403 PACK_NOT_ASSIGNED | Submitted packId is not in tenant assignedPackIds — see Glossary → Pack |
| 401 on partner API | Key revoked, wrong key, or expired credential |
| 403 Forbidden on this UI | Sign in with your staff account, or complete your invitation first. If the page loads but API calls fail, sign out and sign in again. |
| 401 Unauthorized on API calls | Session expired — sign in again (email, password, then email OTP). |
| Invitation link invalid | Ask another staff admin to resend your invitation from the staff-users API or seed script. |
| Invitation email not received | Check portal users status; resend invite; run phase19_setup_partner_portal_email.sh or share invite URL from admin response |
| No submissions in table | Submissions tab → click Load; widen limit; clear search/filters |
| Raw JSON authentication required instead of login page | GET / must return HTML — redeploy phase19_deploy_admin_api.sh if this recurs. |
| 404 error banner on load | Use phase19_admin_ui_local_dev.sh or Cloud Run proxy — not static admin-ui.html |
| Empty Stats dashboard | Click Refresh dashboard; widen day window; redeploy admin-api if message persists |
Support
For any issue with this portal, contact info@idunox.com.
External links
- Staff admin: admin-test.idunox.com
- Partner portal: partner-test.idunox.com/management/api-keys
- Partner API: api-test.idunox.com
- Partner docs: partner-test.idunox.com/docs
Repo runbooks: docs/runbooks/andres-test/PARTNER_ONBOARDING_RUNBOOK.md, PARTNER_PORTAL_API.md, STAFF_ADMIN_AUTH.md