---
title: "Endpoint Reference"
slug: host-portal-endpoints
section: Portals
group: Host Portal
status: stable
description: "The verified API surface of the Host Portal (Alliance-Strategies/HostPortalPrototype, Express + Vite/React), extracted from source on 2026-07-04 (development branch, HEAD 2026-07-01)."
last-updated: 2026-07-04
---

# Endpoint Reference

# Host Portal — Endpoint Reference

The verified API surface of the Host Portal (Alliance-Strategies/HostPortalPrototype, Express + Vite/React), extracted from source on 2026-07-04 (development branch, HEAD 2026-07-01). Routes are mounted at /api from server/routes.ts plus h2b, reservations and globus-webhook sub-routers.

See also: Host Portal governance and Job Orders .

## Auth Reality (Read First)

> **No authentication is enforced in the deployed code**
>
> As of the 2026-07-04 source extraction there is no auth middleware wired anywhere in the Host Portal server: no session store, no Passport, no Auth0 SDK, no route guards. POST /api/auth/login does a plaintext password compare (bcrypt is commented out), GET /api/users/me returns a hardcoded demo user, and handlers that read req.session always see undefined. Every route below is effectively public except the HMAC-verified Globus webhook. The Auth0 configuration (host-portal-qa-auth0-* secrets, AUTH0_DOMAIN / CLIENT_ID / AUDIENCE / MGMT_*) is fully provisioned in k8s ExternalSecrets but has zero code references — the infrastructure is ahead of the application layer. Treat hardening this as a launch blocker for any real-host exposure.

## API Surface by Domain

| Domain | Routes | Notes |
| --- | --- | --- |
| Auth & users | POST /api/auth/login, GET /api/users/me, PATCH /api/users/profile, POST /api/users | Login is a plaintext compare; /users/me returns a hardcoded demo user |
| Job postings (SWT) | GET/POST/PATCH/DELETE /api/jobs(/:id), submit-for-approval, approve, reject, approve-regional, manual-override-approve, :id/matches, :jobId/recommendations, :jobId/extract-skills, :jobId/enhanced-matching | Full posting lifecycle + AI matching (OpenAI/Anthropic) |
| Job orders (H-2B) | GET/POST/PUT/PATCH/DELETE /api/job-orders(/:id), submit, approve, close; /api/h2b/job-orders(/:id), :id/match-participants, :id/matches, :id/documents | Structured job orders + H2B sub-router with participant matching |
| Offers & hires | GET/POST/DELETE /api/job-offers(/:id); GET/POST/PATCH /api/hire-records(/:id), district-location, :participantId | Offer and hire record lifecycle |
| Participants & arrivals | GET/POST /api/your-participants, PATCH :id/job-offer; GET /api/participants/:id, /api/participants-arriving-soon; /api/hanover/participants, /api/hanover/embassy-status | Participant data comes from Hanover MOCK services, not Globus |
| Reservations & shortlist | GET/POST/DELETE /api/reservations(...), reserve, :participantId/decline, :participantId/shortlist, :participantId/interview-dates, process-expired, request-extension, approve-extension | Reservation holds with expiry/extension flows |
| Interviews & applications | GET/POST /api/applications, :id/schedule-interview; GET/POST/PATCH /api/interview-bookings(/:id/outcome), pending-outcome | Interview scheduling and outcome capture |
| Host profiles | GET/POST/PATCH /api/company-profile, /api/camp-profile, /api/teach-profile (+ per-field PATCH) | Offer details, camp overview, TEACH profiles; activity-site data is embedded in job-order/camp payloads |
| Documents & storage | application/company/H2B document CRUD, /api/documents/upload, /api/objects/upload, GET /api/objects/:objectPath, document-expiration force-check/summary, h2b-classification classify/batch/stats | GCS-backed uploads with expiry scanning |
| Training plans & cultural activities | /api/training-plans CRUD + approval/review/clone/history + AI generate; /api/cultural-activities generate + database CRUD; /api/activities | TEACH training-plan lifecycle with AI generation |
| TEACH pipeline | /api/teach/jobs(+stages, stage-summary, status-overview), training-plans linking + signatures, analyze-job, match-candidates, generate-recommendations, districts, campuses, participants, send-email, email-templates, activity metrics | TEACH hiring pipeline; email via SendGrid |
| Notifications, stats, prefs | /api/notifications(+count, read, read-all), /api/stats(+applications, jobs), /api/preferences(+talent-pool, default-sponsor, dashboard-layout), /api/profile/import-* | Dashboard support surfaces |
| Infra & integration | GET /api/health; POST /api/admin/mcp-register; POST /api/globus/webhook; GET /download/prd-html | Health probe, ecosystem registration, inbound Globus webhook |

## Globus Integration

The only real Globus integration today is inbound: POST /api/globus/webhook, verified with HMAC-SHA256 over timestamp.rawBody via the X-Globus-Signature header (secret GLOBUS_WEBHOOK_SECRET, timing-safe compare). It handles workflow.published and workflow.config_published with dedupe, an exponential-backoff retry queue and dead-lettering — but the domain handlers are currently log-only stubs. An outbound GLOBUS_API_KEY is provisioned in Secret Manager yet has no code references: the portal makes no outbound Globus calls yet.

## Actual Upstream Calls

Participant data is fetched from Hanover mock services with no credentials: hanover-mock-services-bmishkin.replit.app, hanover-mock-api.onrender.com and hanover-services.com/mock. AI features call OpenAI and Anthropic; TEACH email goes out via SendGrid. Migrating participant reads from the Hanover mocks to the Globus admin API (using the already-provisioned API key) is the headline integration gap.
