GLYDE Unity + erecruit

GLYDE Unity provides a unified integration with erecruit's WebApi (API v2, erecruit 3.1+), exposing candidate records, internally posted positions, candidate applications, and the full application→sub...

Guide v1.3.0 Unity API v1.34.0 Updated September 29, 2026

Overview

GLYDE Unity provides a unified integration with erecruit's WebApi (API v2, erecruit 3.1+), exposing candidate records, internally posted positions, candidate applications, and the full application→submission→placement pipeline through a single ATS-agnostic API layer.

The integration spans the full GLYDE ecosystem: Microsoft Teams, Copilot for Microsoft 365, Power Automate, the GLYDE Unity SDK, and the Model Context Protocol (MCP) for AI agent consumption. All operations are tenant-isolated using client_uuid and authenticated via OAuth2 client-credentials tokens with fully automatic token management.

erecruit data flows through GLYDE Unity's index-centric normalization pipeline, ensuring consistent data representation across all consumers regardless of erecruit's native conventions — PascalCase payloads, integer entity IDs, and the merged Match pipeline record that collapses application, submission, and placement into one expanding type.

Note: erecruit authentication uses API service credentials — a client ID and client secret for an application registered in the erecruit control panel (per-call permissions are provisioned via Manage API Permissions). GLYDE Unity mints short-lived bearer access tokens via POST {site-origin}/t/token (grant_type=client_credentials); tokens expire every 10 minutes and are renewed automatically. There is no global fallback credential: every client must have tenant credentials plus a per-tenant service_url provisioned in Azure Key Vault / IntegrationData.

Product Demos

Short walkthroughs of the GLYDE experience across the surfaces this integration powers.

Architecture & Data Flow

GLYDE Unity acts as an orchestration layer between consuming platforms (Teams, Copilot, Power Platform, SDK) and the erecruit WebApi REST API. Requests are authenticated, normalized, and routed through the integration adaptor which handles entity-specific business logic, data mapping, and error classification. The erecruit WebApi exposes no API for registering webhooks, so change events are received through a webhook created manually in the erecruit ATS UI pointing at GLYDE (see Events & Webhooks below); until that is set up, index freshness is maintained through scheduled and on-demand cache refresh rather than inbound events.

Teams / Copilot / Power Platform / SDK / MCP Client
                    |
                    v
    ┌─────────────────────────────────────┐
    │     GLYDE Unity REST API            │
    │   api.glydeunity.com/api/unity/*    │
    │                                     │
    │  ┌─ Auth Middleware ─────────────┐   │
    │  │  API Key / JWT / Trusted App │   │
    │  │  Role-based access control   │   │
    │  └──────────────────────────────┘   │
    │                                     │
    │  ┌─ Workflow Route Handler ──────┐  │
    │  │  Validation + Orchestration   │  │
    │  └──────────────────────────────┘   │
    │              |                       │
    │              v                       │
    │  ┌─ erecruit Integration Adaptor┐  │
    │  │  candidates.ts / applications│  │
    │  │  Template Method Pattern     │  │
    │  │  Index-centric data mapping  │  │
    │  └──────────────────────────────┘   │
    │              |                       │
    │              v                       │
    │  ┌─ erecruit External Connector ─┐ │
    │  │  erecruit-connector.ts        │  │
    │  │  ConnectorAuthManager (Bearer)│  │
    │  │  OpenAPI-driven operations    │  │
    │  │  ICanonicalEntityOperations   │  │
    │  └──────────────────────────────┘   │
    │      (inbound events via manual    │
    │       ATS-UI webhook + scheduled   │
    │       cache refresh)               │
    └──────────────|──────────────────────┘
                   |
                   v
    ┌──────────────────────────────────────┐
    │       erecruit WebApi REST API       │
    │  https://.erecruitcloud.com  │
    │                                      │
    │   Candidate | Position |             │
    │   CandidateApplication | Match |     │
    │   Company | Contact | Attachment     │
    └──────────────────────────────────────┘
1
Platform Request

Teams, Copilot, Power Automate, or the SDK sends a request to the GLYDE Unity API (e.g., GET /api/unity/candidates/:candidateUUID) with API key + user context headers.

2
Authentication & Routing

Unity validates the API key, resolves client_uuid and user_uuid, checks role-based access, and routes to the appropriate workflow handler.

3
Adaptor Selection

The workflow handler calls getIntegrationAdaptor('erecruit') to obtain the erecruit-specific adaptor based on the client's configured ATS integration type.

4
Auto-Authentication

The ConnectorAuthManager automatically mints short-lived bearer tokens for the client's erecruit tenant via POST {site-origin}/t/token (grant_type=client_credentials, client_id + client_secret). Sessions are cached in Redis and rotated before the 10-minute token expiry.

5
ATS API Call

The erecruit connector executes the operation against the WebApi using the cleaned OpenAPI specification for request validation and dynamic operation handling. All calls carry Authorization: Bearer {access_token}.

6
Data Normalization

Response data flows through the index-centric pipeline: ATS response → CandidateDataMapper / JobDataMapper / ApplicationDataMapper (driven by types/erecruit/mapping-profile.ts) → canonical index schema. PascalCase fields, _expanded hydration, and integer IDs are resolved entirely inside the mapping profile.

7
Response Delivery

The normalized response is returned to the consuming platform in the GLYDE Unity standard response format, with consistent snake_case field names and structures regardless of erecruit's PascalCase conventions.

8
Cache Refresh

Once the manual ATS-UI webhook is configured, candidate/position/application change events flow into the GLYDE event pipeline and keep the Azure AI Search indexes current. Without the webhook, the indexes are maintained through TTL-based cache capabilities (14,400s hint) and scheduled/on-demand refresh via the ATS search-cache pipeline.

Authentication

OAuth2 Client Credentials (POST {site-origin}/t/token)

erecruit's WebApi (API v2, erecruit 3.1+) uses OAuth2 client-credential token auth. GLYDE Unity's ErecruitConnectorAuthManager (extending BaseBearerTokenAuthManager) handles the complete token lifecycle automatically: it POSTs a form-encoded grant_type=client_credentials&client_id=…&client_secret=…&scope={site-origin} body to {site-origin}/t/token and uses the returned access_token as the bearer token on every subsequent call (Authorization: Bearer {access_token}). Clients never need to manage tokens directly. Credentials are API service credentials for an application registered in the erecruit control panel; per-call permissions are provisioned via Manage API Permissions.

Naming note: the swagger document's info.version string reads "v1" — that is the DOC version, not the legacy RESTServices API v1 product (a separate XML/cookie surface at /RestServices, available only for erecruit 3.0 and earlier). The /webapi swagger is the WebApi product documentation, and POST {site-origin}/t/token was verified live on the Nelson Connects sandbox (standard OAuth2 unauthorized_client response for dummy credentials); the checked-in cleaned spec matches the live tenant path-for-path (198 paths / 230 operations).

Credential Fields

FieldDescriptionRequired
client_id Client ID of the application registered in the erecruit control panel Yes
client_secret Client secret issued for the registered application Yes
service_url Base URL for the tenant's erecruit WebApi, e.g. https://nelsonupgrade.erecruitcloud.com/webapi — erecruit hosts are per-tenant, so this is effectively required (ERECRUIT_API_URL env is a deployment-level fallback only) Yes
tenant Optional tenant EntityID — legacy v1 context only; NOT required for v2 token auth No

Session Management

Sessions are cached in Redis with the key pattern session:client:{client_uuid}:integration:erecruit. The session stores the bearer access token, expiration timestamp, resolved base URL, and optional entity id. There is no global fallback credential — every tenant must have credentials provisioned in Azure Key Vault / IntegrationData (getDefaultAuthConfig throws).

Token Refresh

Access tokens expire every 10 minutes per the Bullhorn KB; the token response's expires_in is honored (600s default when omitted). Sessions rotate automatically: the 5-minute validity buffer re-mints the token well before expiry, and a 401 from the ATS triggers clearRedisSessionOnly() and a single retry with a freshly minted token.

Capabilities

📦 Two API layers, one integration

This integration exposes erecruit through two distinct layers, and every capability below tells you which layer it runs on. Reading the table without this context is the most common source of confusion, so here is the distinction:

1. GLYDE Unity workflow endpoints (the Endpoint column) are GLYDE's own, ATS-agnostic APIs (/api/unity/*). They are the recommended path for every consumer — Teams, Copilot, Power Automate, the Chrome Extension, and the SDK. Each one is an orchestrated workflow: GLYDE handles authentication, tenant isolation, validation, data normalization into GLYDE's canonical format, database sync, and search indexing. You talk to GLYDE in GLYDE's vocabulary; GLYDE talks to the ATS behind the scenes.

2. ATS proxied calls (the ATS Op column) are the raw erecruit REST operations the workflow invokes under the hood. You normally never call these directly — but you can, through the ATS proxy (/api/unity/proxy/erecruit/:operationId and the discover/inspect meta-operations). The proxy executes any operation from erecruit's OpenAPI specification verbatim: request and response shapes are the vendor's own, no GLYDE normalization is applied. Use it for advanced or niche operations GLYDE has not (yet) wrapped in a workflow — it inherits GLYDE's authentication, tenant isolation, and OAuth token management, but you are speaking the vendor's dialect, so field names, casing, and payloads match the erecruit spec exactly.

Rule of thumb: start with the workflow layer; drop to the proxy only when a workflow for what you need does not exist.

Status badges on each capability card grade the workflow layer coverage for that entity:

  • full — complete workflow coverage: create, read, update (where the ATS API allows it), and GLYDE-side persistence/indexing all work.
  • partial — the entity is supported, but one or more workflow operations are unavailable, not supported by the ATS API itself, or served differently (e.g. reads resolved from the GLYDE search index instead of a live ATS call, missing job-note support, or a NOT_IMPLEMENTED update). Read each operation's notes for the specific gap. The raw operations may still be reachable through the ATS proxy.
  • proxy only — no GLYDE workflow wraps this entity; access is exclusively via raw proxied ATS calls with vendor-native payloads.
  • not supported — neither a workflow nor a usable proxy operation exists for this entity.
Candidates partial
OperationEndpointATS Op
Get Candidate
Index-first retrieval by GLYDE UUID or ATS candidate ID with live/Redis cache merge
GET /api/unity/candidates/:candidateUUID Candidate_Get
Search Candidates (Live Reinforcement)
Weighted search fusing GLYDE indexes with a live erecruit candidate list
POST /api/unity/search/searchCandidates Candidate_List
Find Candidate (Dedup Lookup)
Deterministic lookup (email → phone → name) used by create-or-reuse flows
internal internal (createOrReuseCandidate) Candidate_List / Candidate_ByName
Jobs (Positions) partial
OperationEndpointATS Op
Search Jobs (Live Reinforcement)
Weighted search fusing the GLYDE jobs index with live internally posted positions
POST /api/unity/search/searchJobs Position_GetInternallyPosted
Get Job
Retrieved from the GLYDE search index (no live get-by-id fetch hook on the adaptor)
GET /api/unity/jobs/:jobUUID None (index-only)
Applications partial
OperationEndpointATS Op
Create Application
Link a candidate to a position with a new CandidateApplication record
POST /api/unity/applications CandidateApplication_Post
List Applications by Candidate
Canonical candidate-scoped application list feeding the ATS search-cache pipeline
internal internal (ats-search-cache pipeline) CandidateApplication_GetByCandidateId
List Applications by Position
Position-scoped application list — reachable through the ATS proxy
proxy /api/unity/proxy/erecruit/CandidateApplication_GetByPositionId CandidateApplication_GetByPositionId
Find Application
Candidate- or job-scoped application lookup on the ATS-agnostic filter surface
POST /api/unity/applications/find CandidateApplication_GetByCandidateId / GetByPositionId
Match (Submission / Placement Pipeline) proxy only
OperationEndpointATS Op
Pipeline Records by Candidate
Application→submission→placement pipeline records for one candidate
proxy /api/unity/proxy/erecruit/Match_GetByCandidateId Match_GetByCandidateId
Pipeline Record by ID
Read one match (pipeline) record by integer ID
proxy /api/unity/proxy/erecruit/Match_GetById Match_GetById
Messages (Email / SMS) proxy only
OperationEndpointATS Op
Send Email
Send email via Mailgun through the base messages adaptor
POST /api/unity/messages/send-email Mailgun (no erecruit activity write-back)
Send SMS
Send SMS via Twilio through the base messages adaptor
POST /api/unity/sms/send Twilio (no erecruit activity write-back)
Companies & Contacts (Directory) full
OperationEndpointATS Op
Search Companies
Search the GLYDE company/client directory (name, industry, status, location) across connected tenants
POST /api/unity/search/searchCompanies GLYDE directory index (ats-cache-company-index)
Search Contacts
Search the GLYDE contact directory (names, emails, phones, titles) with denormalized company references
POST /api/unity/search/searchContacts GLYDE directory index (ats-cache-company-index)
Company / Contact Pickers
value/label option lists powering dynamic lookup dropdowns in Power Automate and Make.com
POST /api/unity/directory/companyOptions + /api/unity/directory/contactOptions Directory search legs
Import Directory Rows
Merge parsed company/contact rows into the directory from any source format (CSV, TSV, pasted text, Excel copied as text) — the calling model converts the source into structured rows
POST /api/unity/directory/ingest Directory index mergeOrUpload (origin: import)
Search (AI-Powered) full
OperationEndpointATS Op
Weighted Candidate Search
Fused GLYDE index + live erecruit candidate search with ranking
POST /api/unity/search/searchCandidates Candidate_List (live reinforcement)
Weighted Job Search
Fused GLYDE index + live erecruit position search with ranking
POST /api/unity/search/searchJobs Position_GetInternallyPosted (live reinforcement)
Conversational AI Search
Natural-language search across candidates and jobs using GLYDE AI
POST /api/unity/search/conversationalAISearch Azure AI Search Index (not direct ATS)
Index Query
Structured OData queries against tenant-scoped GLYDE indexes
POST /api/unity/search/aiSearchIndex Azure AI Search Index
ATS Proxy (Discovery & Execute) full
OperationEndpointATS Op
Discover Operations
List all available erecruit WebApi operations (230 across 198 paths) with schemas and metadata
GET /api/unity/proxy/discover/erecruit OpenAPI spec introspection
Inspect Operation
Full specification for one erecruit operation
GET /api/unity/proxy/inspect/erecruit/:operationId OpenAPI schema introspection
Execute Operation
Execute any of the 230 erecruit spec operations dynamically with vendor-native payloads
POST /api/unity/proxy/erecruit/:operationId Dynamic (per operationId)
Entity Metadata
Field-level metadata for an erecruit entity type, including designer-bound lookup catalogs
GET /api/unity/proxy/meta/erecruit/:entity OpenAPI schema + fieldValueOperations
Events & Webhooks (Inbound) partial
OperationEndpointATS Op
Receive Event Webhook
Inbound erecruit change events via a webhook created manually in the erecruit ATS UI (the WebApi has no subscription-registration endpoints)
POST /api/unity/events/webhook/:client_uuid/erecruit Manual ATS-UI webhook (Candidate.* / Position.* / CandidateApplication.*)

Platform Access

GLYDE Unity provides unified access to erecruit across multiple Microsoft 365 and developer platforms.

💬 Microsoft Teams

Access erecruit data through the GLYDE Unity bot in Teams channels and chats.

Access: Teams Bot Framework → GLYDEBuddy Proxy → Unity REST API → erecruit Adaptor

  • Search candidates and jobs via conversational AI
  • View candidate profiles with live erecruit field merge
  • Review application status and the Match pipeline stage
  • Send emails and SMS through GLYDE-native channels
✨ Copilot for Microsoft 365

Use natural language to interact with erecruit data through the GLYDE Copilot declarative agent.

Access: Copilot Agent → MCP Bridge (GLYDEBuddy) → Unity REST API → erecruit Adaptor

  • Natural language queries ("Show me internally posted positions")
  • Tier-1 weighted searches with live erecruit reinforcement
  • ATS proxy operations for advanced queries (discover → inspect → execute)
  • Entity aliasing resolves GLYDE terms to erecruit vocabulary (job → Position, submission/placement → Match) via atsProfile
  • Operation hints steer agents to the right list/read operation (Candidate_List vs Candidate_Get, etc.)
⚡ Power Automate / Power Apps

Automate erecruit workflows using the GLYDE Unity Power Platform connector.

Access: Power Platform Connector → Unity REST API → erecruit Adaptor

  • Create applications linking candidates to positions
  • Run weighted candidate and job searches
  • Execute any erecruit spec operation through the ATS proxy
  • Designer-bound dropdowns for StatusID / TypeID / RatingID and other lookups via cached inspect inputs
  • Note: ATS change triggers depend on the manual ATS-UI webhook being configured (see Events & Webhooks); without it, use polling schedules
📦 GLYDE Unity SDK

Programmatic access via the @glydeunity/glyde-api-client npm package.

Access: SDK Client → Unity REST API → erecruit Adaptor

  • Type-safe TypeScript API client with Zod validation
  • FlexibleUnityApi for multiple input formats (UUID, ATS ID, object)
  • Direct workflow operations and ATS proxy access
  • Automatic authentication and session management
  • OpenAPI-generated client with full IntelliSense
🤖 MCP (Model Context Protocol)

AI agents and LLMs access erecruit operations through the MCP interface.

Access: MCP Client → Unity MCP Endpoints → Workflow Handlers → erecruit Adaptor

  • 100+ discoverable tools auto-generated from workflow routes
  • ATS proxy tools for dynamic operation discovery and execution
  • Entity metadata tools for field-level schema inspection
  • Filtered schemas (x-NoMCP fields excluded for security)
  • JSON-RPC and REST invocation protocols
🎤 GLYDE Voice Agent

Voice-based interaction for candidate screening and job discovery (ATS-agnostic).

Access: Voice SDK → Unity Voice API → Deepgram → Function Execution

  • Voice-powered candidate screening interviews
  • Job discovery and application via voice
  • Real-time candidate creation during conversations
  • OTP verification for candidate identity

Entity Mappings

erecruit uses different entity names and field conventions. GLYDE Unity normalizes these through the index-centric data pipeline.

Candidate → Candidate

Unity Fielderecruit FieldDirectionNotes
first_name First Read —
last_name Last Read —
middle_name Middle Read —
last_job_title Title Read —
last_employer CurrentEmployer Read —
availability DateAvailable Read —
email _expanded.Communications[] Read Primary-wins, Category-labelled (email)
phone _expanded.Communications[] Read Primary-wins, Category-labelled (phone/mobile)
city / state / zip / address _expanded.DefaultAddress.{City,State,PostalCode,AddressLine1} Read Requires the expand query parameter
country _expanded.DefaultAddress.Country Read —
employment_type_preferences IsLookingForPerm / IsLookingForContract / IsLookingForContractToPerm Read Boolean flags folded into a preferences array
ats_candidate_id ID Read Integer; candidate_uuid resolved via ExternalMappings
StatusID / RatingID / AdSource StatusID / RatingID / AdSource Read Tracked as lookups (NamedValue catalogs) — not flattened into the index

Job → Position (PostedPositionResponse)

Unity Fielderecruit FieldDirectionNotes
title Title / PositionTitle Read —
ats_job_id ID Read Integer
description WebDescription Read Falls back to _expanded.Description.Text
status _expanded.Status.Name Read StatusID is the raw integer ref; the label only appears when expanded
employment_type PositionType / _expanded.Type.Name Read —
department PrimaryDepartmentName Read —
company_name / company CompanyName / _expanded.Company.Name Read —
company_id / contact_id CompanyID / ContactID Read —
external_id ExternalPositionID Read —
min_bill_rate / max_bill_rate MinBillRate / MaxBillRate Read —
min_pay_rate / max_pay_rate MinPayRate / MaxPayRate Read —
salary_min / salary_max HourlyMin / AnnualMin · HourlyMax / AnnualMax Read —
start_date / end_date StartDate / EndDate Read —
date_posted / updated DatePosted / DateLastOpened Read —
recruiter_name RecruiterName Read —
city / state / zip / address PrimaryAddress.{City,State,PostalCode,AddressLine1} Read Also _expanded.DefaultAddress on PositionResponse

Application → CandidateApplication

Unity Fielderecruit FieldDirectionNotes
ats_application_id ID Read Integer (PascalCase)
ats_candidate_id CandidateID Read —
ats_job_id PositionID Read —
ats_match_id MatchID Read Links to the pipeline (Match) record
status / ats_status Status Read String label (unlike Candidate/Position integer StatusIDs)
rejection_reason RejectionReason Read —
rejected_on RejectedOn Read —
application_source AdSource Read —
note Note Read —
created / modified CreatedOn Read CreatedOn feeds both; no separate modified timestamp
CandidateID / PositionID (create) CandidateApplicationRequest Write Create posts { CandidateID, PositionID, ApplicationSourceID?, ApplicationNote? } to CandidateApplication_Post

Placement / Submission → Match

Unity Fielderecruit FieldDirectionNotes
(pipeline stage) MatchResponse.Status Read Application→submission→placement as ONE expanding record; Status is the stage label ("Submitted", "Placed")
(hydrated context) MatchResponse._expanded Read Carries Candidate / Position / Company / DefaultAddress when expanded
(link) CandidateApplication.MatchID Read Applications link to their pipeline record via MatchID

Endpoint Reference

MethodUnity EndpointDescriptionATS OperationAuth
GET /api/unity/candidates/:uuid Get candidate by ID (live Candidate_Get + cache merge) Candidate_Get API Key + User UUID
POST /api/unity/search/searchCandidates Weighted candidate search with live reinforcement Candidate_List API Key + User UUID
POST /api/unity/search/searchJobs Weighted job search with live reinforcement Position_GetInternallyPosted API Key + User UUID
POST /api/unity/search/conversationalAISearch AI-powered natural language search (GLYDE index) Azure AI Search API Key + User UUID
POST /api/unity/search/searchCompanies Search the company/client directory (live erecruit search + GLYDE index) erecruit directory search API Key + User UUID
POST /api/unity/search/searchContacts Search the contact directory with denormalized company refs erecruit directory search API Key + User UUID
POST /api/unity/directory/companyOptions Company picker options for dynamic lookup Directory search legs API Key + User UUID
POST /api/unity/directory/contactOptions Contact picker options, optionally company-scoped Directory search legs API Key + User UUID
POST /api/unity/directory/ingest Import parsed company/contact rows (any source format) into the directory Directory index mergeOrUpload API Key + User UUID
POST /api/unity/search/aiSearchIndex Structured OData index query Azure AI Search API Key + User UUID
POST /api/unity/applications Create application (CandidateApplication_Post) CandidateApplication_Post API Key + User UUID
POST /api/unity/applications/find Find applications by candidate/job filter CandidateApplication_GetByCandidateId / GetByPositionId API Key + User UUID
POST /api/unity/messages/send-email Send email (Mailgun, no ATS activity write-back) Mailgun API Key + User UUID
POST /api/unity/sms/send Send SMS (Twilio, no ATS activity write-back) Twilio API Key + User UUID
GET /api/unity/proxy/discover/erecruit Discover all 230 erecruit operations OpenAPI introspection API Key + User UUID
GET /api/unity/proxy/inspect/erecruit/:opId Inspect one operation (full spec) Schema introspection API Key + User UUID
POST /api/unity/proxy/erecruit/:opId Execute any erecruit spec operation (e.g. Match_GetByCandidateId, Position_GetPosition) Dynamic API Key + User UUID
GET /api/unity/proxy/meta/erecruit/:entity Get entity metadata + lookup catalogs Schema + fieldValueOperations API Key + User UUID

Events & Webhooks

Inbound erecruit change events are supported through a webhook that is created manually in the erecruit ATS UI — the erecruit WebApi exposes no endpoint for registering subscriptions programmatically (remote_subscription_supported: false), so a one-time manual setup in the ATS administration UI is required. Events are processed through the GLYDE ATS event pipeline: they keep the candidate/job indexes current (gated by the tenant's event_system.processing.update_ats_cache setting) and are the primary way candidate records first flow into GLYDE, because the WebApi has no candidate-enumeration search (listing requires vendor/status/owner filters or an exact name).

Manual webhook setup:

  1. In the erecruit ATS administration UI, create a webhook (event subscription) for Candidate, Position, and CandidateApplication change events.
  2. Point it at the GLYDE event receiver for this tenant: POST https://api.glydeunity.com/api/unity/events/webhook/{client_uuid}/erecruit — the tenant's GLYDE client_uuid is embedded in the URL, so no tenant resolution is required in the payload. (An alternative form, POST /api/unity/events/webhook/erecruit, exists for senders that pass the clientUuid query parameter instead.)
  3. Ask GLYDE support to enable the erecruit-core-events subscription on the tenant — it is born disabled on purpose (events arriving before the webhook exists are rejected with 404). After enabling, run POST /api/unity/activation/verify — the events phase should report healthy and go-live (initial index population) can proceed.
By default no signature or auth header is required on the webhook (the tenant-scoped URL is the identifier); a bearer-token or shared-key check can be configured on the subscription if the ATS UI supports custom headers. Until the webhook is set up, index freshness relies on the TTL-based cache strategy (14,400s hint) and scheduled / on-demand refresh via the ATS search-cache pipeline.

EventTriggerPayloadAutomatic Actions
Candidate.* Candidate record created/updated/deleted in erecruit Candidate change payload (passthrough-normalized into the GLYDE ATS event format) Candidate cache refresh: profile re-fetched from the WebApi, normalized, and re-indexed (gated by event_system.processing.update_ats_cache) — also the initial-population path that mints candidate records into the GLYDE index
Position.* Position (job) record changed in erecruit Position change payload (passthrough-normalized) Job index refresh + jobs-index ingest so weighted job search reflects the change
CandidateApplication.* Application / Match pipeline record changed in erecruit CandidateApplication change payload (passthrough-normalized) Candidate cache refresh + application/pipeline data refresh for the affected candidate and position

Configuration Requirements

  • erecruit API Service Credentials (Client ID / Client Secret)REQUIRED

    Client ID + client secret for an application registered in the erecruit control panel, with the needed calls enabled under Manage API Permissions (per-call permissions). These must be stored in Azure Key Vault via the GLYDE Unity client configuration; there is no global fallback credential.

    client_id: "glu-integration-app"

  • Tenant service_url (WebApi Base URL)REQUIRED

    Per-tenant erecruit WebApi base URL — must include the /webapi path (e.g. https://<agency>.erecruitcloud.com/webapi): data calls are made against this base, while the token endpoint is derived from the site origin ({origin}/t/token), so a URL missing /webapi still mints tokens but fails every data call. Resolution order: tenant service_url → ERECRUIT_API_URL env. The activation wizard’s verification pass (POST /api/unity/activation/verify) live-probes stored credentials with one cheap read call, so a malformed base URL is caught at setup time instead of at first use.

    service_url: "https://nelsonupgrade.erecruitcloud.com/webapi"

  • EntityID (Tenant Identifier, optional)

    Legacy v1 context only — NOT required for v2 token auth. Stored as UnityCredentials.tenant when provided.

    tenant: "3"

  • Integration TypeREQUIRED

    The client's integration_type must be set to "erecruit" in the GLYDE client configuration for the adaptor router to select the correct integration.

    integration_type: "erecruit"

Known Limitations

  • Events require manual webhook setup. The erecruit WebApi has no subscription-registration endpoints, so the inbound webhook must be created manually in the erecruit ATS UI pointing at POST /api/unity/events/webhook/{client_uuid}/erecruit, and the erecruit-core-events subscription enabled by GLYDE support (it is born disabled). Until then, index freshness relies on TTL + scheduled cache refresh, and candidate records only enter GLYDE through searches and explicit reads.
  • No candidate-enumeration search. Candidate_List requires at least one of VendorID/StatusIDs/OwnerID, and Candidate_ByName is an exact First+Last lookup — the WebApi has no "list all candidates" operation, which is why inbound events are the primary initial-population path for candidates.
  • No server-side pagination on core lists. Candidate_List, Position_GetInternallyPosted, and the CandidateApplication list operations return the FULL list — filter client-side.
  • No keyword search. Search is structured-filter only (VendorID, StatusIDs, OwnerID, name parts). searchCapabilities.supportsKeywordSearch is false; keyword-style discovery is served from the GLYDE Azure AI Search index.
  • Field names are PascalCase (First, Last, ID, StatusID) — not camelCase or snake_case. All mapping lives in types/erecruit/mapping-profile.ts.
  • Entity IDs are integers; Match/CandidateApplication cross-reference them via CandidateID / PositionID / MatchID.
  • Match is the pipeline record: application → submission → placement as ONE expanding record (Status is the stage label). There is no separate GLYDE placement entity — Match is registered with canonicalEntity: "other".
  • Auth uses API service credentials (client_id + client_secret for an application registered in the control panel, permissions via Manage API Permissions); POST {site-origin}/t/token returns the bearer access_token.
  • Access tokens expire every 10 minutes — sessions rotate automatically off the response expires_in (600s default) and the 5-minute validity buffer.
  • Status labels require expansion. Candidate/Position records carry integer StatusID refs; labels only appear in _expanded.Status.Name (requires the expand query parameter). Applications are the exception — they carry string Status labels directly.
  • Statuses/types are NamedValue { ID, Name } lookups (Position_GetStatuses / Position_GetTypes / Candidate_GetRatings / AdSource_GetAdSources, etc.) consumed via fieldValueOperations for designer dropdowns.
  • Candidate create/update are not implemented at the workflow layer (the adaptor inherits the base not-supported defaults). Candidate records flow in through list/get and the search-cache pipeline; use the ATS proxy for vendor-native writes.
  • Job create/update are not implemented and live job get-by-id resolves from the GLYDE index; live single-position reads are available via Position_GetPosition through the ATS proxy.
  • No ATS activity write-back for messages. Email/SMS delivery is GLYDE-native (Mailgun/Twilio); no erecruit activity note is created. Use the ATS proxy for vendor-native note operations.
  • Addresses use PostalCode / AddressLine1 (not Zip / Address1).
  • HireDate / ReHireDate on candidates are placement dates, NOT record timestamps — deliberately never mapped to created/updated. EducationLeveID is a vendor typo on CandidateResponse and is unmapped by design.
  • Outbound create/update field mapping beyond CandidateApplication_Post is not yet implemented in the mapping profile — it defines the inbound field maps used by the ATS search-index pipeline.

Version History

v1.3.0 2026-09-29
  • Documented the manual ATS-UI webhook events model end to end: the WebApi has no subscription-registration endpoints, so the inbound webhook is created manually in the erecruit ATS UI pointing at POST https://api.glydeunity.com/api/unity/events/webhook/{client_uuid}/erecruit, and the erecruit-core-events subscription (born disabled) is enabled by GLYDE support once the webhook exists. Refreshed the Events section, architecture summary, diagram, endpoint table, and Power Platform notes that previously stated "no webhooks".
  • Clarified service_url MUST include the /webapi path — the token endpoint is origin-derived so a malformed base still mints tokens while data calls fail; documented the activation live credential probe (token mint + one cheap read) that now catches this at setup time.
  • Documented that inbound events are the primary initial-population path for candidates (no candidate-enumeration search in the WebApi: Candidate_List requires vendor/status/owner filters, Candidate_ByName is exact-match).
  • Proxy operations for erecruit are default-allowed at the platform operation-permission gate (a missing per-ATS entry previously denied every direct ATS operation with 403 before the connector was invoked).
v1.2.0 2026-09-28
  • Migrated authentication from the legacy v1 user login (User/ValidateCredentials with UserName + Password + mandatory EntityID) to the WebApi v2 OAuth2 client-credentials flow per the official Bullhorn KB: POST {site-origin}/t/token with client_id + client_secret, bearer access_token, 10-minute expiry honored via expires_in.
  • Credentials are now API service credentials (client_id + client_secret stored as UnityCredentials.client_id / client_secret); EntityID became optional context and service_url is effectively required (per-tenant hosts).
  • Documented control-panel application registration + Manage API Permissions prerequisites; refreshed configuration requirements, known limitations, and gotchas accordingly.
v1.1.0 2026-09-12
  • Companies & Contacts: directory search endpoints added — searchCompanies/searchContacts over the GLYDE directory index, picker endpoints for Power Automate/Make.com dynamic lookup, and unityIngestDirectoryData for parsed imports from any source format (recruiter + support agents). Live erecruit company/contact reads remain available via the proxy (Company_Filter/Contact_Filter).
v1.0.0 2026-08-26
  • Initial integration guide creation
  • Documented bearer-token authentication via User_ValidateCredentials (UserName + Password + mandatory EntityID)
  • Documented candidate retrieval with live/cache merge and weighted search live reinforcement
  • Documented job (Position) search via Position_GetInternallyPosted and index-only get-by-id
  • Documented application create/find/list operations (CandidateApplication_Post, GetByCandidateId, GetByPositionId)
  • Documented the Match pipeline record (application→submission→placement as one expanding type)
  • Documented ATS proxy discovery/inspection/execution across all 230 spec operations
  • Documented the NamedValue lookup catalogs feeding designer dropdowns
  • Documented the no-webhook event model with TTL + scheduled cache refresh
  • Documented platform access patterns (Teams, Copilot, Power Platform, SDK, MCP, Voice)
  • Documented entity mappings (Candidate, Position, CandidateApplication, Match)
  • Documented configuration requirements and known limitations