Overview
GLYDE Unity provides a comprehensive, bi-directional integration with AviontéBOLD, the staffing industry's enterprise applicant tracking and workforce management platform. This integration enables recruiters, hiring managers, and AI agents to access Avionté talent records, job postings, applications, and activities through a unified API layer.
The integration spans the full GLYDE ecosystem: Microsoft Teams, Copilot for Microsoft 365,
Power Automate, the GLYDE Chrome Extension, 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 with automatic token management.
Avionté data flows through GLYDE Unity's index-centric normalization pipeline, ensuring consistent data representation across all consumers regardless of Avionté's native field naming conventions (e.g., "Talent" instead of "Candidate", "Assignment" instead of "Placement"). Because Avionté exposes no search API for talent, jobs, companies, or contacts, GLYDE maintains its own Azure AI Search indexes and keeps them current through a smart background indexing pipeline — fed by Avionté webhooks, the GLYDE Dock for Avionté browser companion, and write-back from live reads. See Smart Background Indexing below for how that works and API Usage Metering / Data Privacy & PII for the platform services wrapped around it.
Product Demos
Short walkthroughs of the GLYDE experience across the surfaces this integration powers.
Watch it work
1 / 6Architecture & Data Flow
GLYDE Unity acts as an orchestration layer between consuming platforms (Teams, Copilot, Power Platform, SDK) and the AviontéBOLD REST API. Requests are authenticated, normalized, and routed through the integration adaptor which handles entity-specific business logic, data mapping, and error classification.
Teams / Copilot / Power Platform / Chrome Ext / 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 │
│ ┌─ Avionté Integration Adaptor ─┐ │
│ │ candidates.ts / jobs / etc. │ │
│ │ Template Method Pattern │ │
│ │ Data Mapping (Index-centric) │ │
│ └──────────────────────────────┘ │
│ | │
│ v │
│ ┌─ Avionté External Connector ──┐ │
│ │ avionte-connector.ts │ │
│ │ ConnectorAuthManager (OAuth2)│ │
│ │ OpenAPI-driven operations │ │
│ └──────────────────────────────┘ │
│ ^ │
│ │ webhooks (inbound) │
│ ┌─ Event Normalizer ────────────┐ │
│ │ AvionteEventNormalizer │ │
│ │ FrontOfficeTenantId → │ │
│ │ tenant resolution │ │
│ └──────────────────────────────┘ │
└──────────────|──────────────────────┘
|
v
┌──────────────────────────────────────┐
│ AviontéBOLD REST API │
│ {tenant}.avionte.com/api/v1/* │
│ │
│ Talent | Job | Application | │
│ Company | Assignment | Activity │
└──────────────────────────────────────┘
Teams, Copilot, Power Automate, the GLYDE Chrome Extension, or SDK sends a request to the GLYDE Unity API (e.g., POST /api/unity/candidates) with API key + user context headers (extension calls use a scoped publishable key).
Unity validates the API key, resolves client_uuid and user_uuid, checks role-based access, and routes to the appropriate workflow handler.
The workflow handler calls getIntegrationAdaptor('avionte') to obtain the Avionté-specific adaptor based on the client's configured ATS integration type.
The ConnectorAuthManager automatically retrieves or refreshes OAuth2 tokens for the client's Avionté tenant. Sessions are cached in Redis with automatic expiration.
The Avionté connector executes the operation against the AviontéBOLD REST API using the OpenAPI specification for request validation and dynamic operation handling.
Response data flows through the index-centric pipeline: ATS response → CandidateDataMapper → ATSCacheCandidateSearchIndex (canonical format) → searchIndexToCandidate() → CRUD schema.
The normalized response is returned to the consuming platform in the GLYDE Unity standard response format, with consistent field names and structures regardless of ATS-specific conventions.
Inbound Avionté webhooks (/api/unity/events/webhook/avionte) and talent IDs harvested by the GLYDE Dock for Avionté feed the ATS search-cache queue, keeping the GLYDE Azure AI Search indexes current between scheduled syncs. See Smart Background Indexing for the full pipeline.
Authentication
OAuth2 Client Credentials
Avionté uses OAuth2 client credentials flow for machine-to-machine authentication.
GLYDE Unity's ConnectorAuthManager handles the complete token lifecycle automatically:
initial authentication, session caching in Redis, token refresh before expiration, and tenant header injection.
Clients never need to manage tokens directly.
Credential Fields
| Field | Description | Required |
|---|---|---|
client_id |
OAuth2 client identifier issued by Avionté | Yes |
client_secret |
OAuth2 client secret for token exchange | Yes |
tenant |
Avionté tenant identifier (injected as Tenant header on all API calls) | Yes |
x_api_key |
Optional API key sent as X-Api-Key header for additional authorization | No |
service_url |
Base URL for the AviontéBOLD API (defaults to standard endpoint) | No |
auth_url |
OAuth2 token endpoint URL (defaults to /authorize/token) | No |
Session Management
Sessions are cached in Redis with the key pattern session:client:{client_uuid}:integration:avionte (encrypted Unity session blob).
The session includes the OAuth2 access token, expiration timestamp, tenant identifier, and resolved service URL.
TTL follows the platform profile (default connector cache window). Sessions are re-validated on each request via ConnectorAuthManager.
Token Refresh
The AvionteConnectorAuthManager checks token expiration before each API call.
If the token is expired or within the refresh threshold, a new token is obtained via the client credentials flow.
The OAuth2 scope is avionte.aero.compasintegrationservice. JWT tokens are validated
for expiration using the exp claim.
Capabilities
📦 Two API layers, one integration
This integration exposes AviontéBOLD 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 AviontéBOLD REST operations the workflow
invokes under the hood. You normally never call these directly — but you can, through the
ATS proxy (/api/unity/proxy/avionte/:operationId and the discover/inspect meta-operations).
The proxy executes any operation from AviontéBOLD'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 AviontéBOLD 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_IMPLEMENTEDupdate). 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.
| Operation | Endpoint | ATS Op |
|---|---|---|
| Create Candidate Create a new talent record in Avionté with GLYDE DB sync and search indexing |
POST /api/unity/candidates |
CreateTalent |
| Create-or-Reuse Candidate Create new talent, or reuse an existing one when Avionté returns 409 Duplicate talent |
POST /api/unity/candidates |
CreateTalent + QueryMultipleTalents |
| Get Candidate Retrieve talent by GLYDE UUID or Avionté talent ID with live/Redis cache merge |
GET /api/unity/candidates/:candidateUUID |
QueryMultipleTalents |
| Update Candidate Update talent record (full PUT, not PATCH) with change propagation |
PUT /api/unity/candidates/:candidateUUID |
GetTalent + UpdateTalent |
| Search Candidates Avionté exposes no search/filter API for Talent. Candidate search is served from the GLYDE Azure AI Search index |
POST /api/unity/search/aiSearchIndex |
None (index-only) |
| Operation | Endpoint | ATS Op |
|---|---|---|
| Create Job Create a new job posting in Avionté |
POST /api/unity/jobs |
CreateJob |
| Update Job Update job posting (full PUT). Resolves the job via UUID or ats_job_id; jobId is routed to the spec path param automatically |
PUT /api/unity/jobs/:jobUUID |
UpdateJob |
| Get Job Retrieved from the GLYDE search index (no live ATS get-by-id fallback) |
GET /api/unity/jobs/:jobUUID |
None (index-only) |
| Search Jobs Avionté exposes no search/filter API for Jobs. Job search is served from the GLYDE Azure AI Search index |
POST /api/unity/search/aiSearchIndex |
None (index-only) |
| Operation | Endpoint | ATS Op |
|---|---|---|
| Search Companies Search the GLYDE-cached Avionté company/client directory (name, industry, status, location) with free text and/or structured OData filters |
POST /api/unity/search/searchCompanies |
Azure AI Search ats-cache-company-index (event-fed) |
| Search Contacts Search the contact directory (names, emails, phones, titles) with denormalized company references |
POST /api/unity/search/searchContacts |
Azure AI Search ats-cache-contact-index (event-fed) |
| 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 indexes |
| Import Directory Rows Merge parsed company/contact rows into the directory from any source format (CSV, TSV, pasted text, Excel copied as text) |
POST /api/unity/directory/ingest |
Azure AI Search mergeOrUpload (origin: import) |
| Live Company / Contact Reads Raw Avionté company/contact reads stay available through the ATS proxy |
POST /api/unity/proxy/avionte/:operationId |
CompanyIds, QueryMultipleCompanies, GetCompany, ContactIds, QueryMultipleContacts, GetContact, ContactSearch |
| Operation | Endpoint | ATS Op |
|---|---|---|
| Create Application Submit a web applicant linking talent to a job via CreateWebApplicant |
POST /api/unity/applications |
CreateWebApplicant |
| Get Application Retrieve application by UUID |
GET /api/unity/applications/:applicationUUID |
getApplication |
| Get Job Applications Retrieve web applicants for a job through the ATS-agnostic Unity workflow |
POST /api/unity/applications/job/latest |
GetWebApplicantsForJob |
| List Applications by Candidate Three-tier fetch with job enrichment and status resolution, feeding the ATS search cache pipeline |
POST /api/unity/ats/search-cache/enqueue-candidates (internal) |
GetWebApplicationsForTalent + GetTalentStagesForJob |
| Find Application Job-scoped web-applicant lookup on the ATS-agnostic filter surface |
POST /api/unity/applications/find |
GetTalentStagesForJob |
| Operation | Endpoint | ATS Op |
|---|---|---|
| Send Email Send email via Mailgun with automatic activity logging to Avionté |
POST /api/unity/messages/send-email |
Mailgun + /v1/talent/{id}/activity |
| Send SMS Send SMS via Twilio through the base messages adaptor |
POST /api/unity/sms/send |
Twilio → Avionté CreateTalentActivity (communication write-back queue) |
| Operation | Endpoint | ATS Op |
|---|---|---|
| Create Note (Unified) Create a talent activity note via the unified activities workflow (ATS write + optional GLYDE timeline) |
POST /api/unity/activities |
CreateTalentActivity |
| Add Candidate Note (Legacy) Legacy email/logging path that creates an activity note on a talent record in Avionté |
POST /api/unity/candidates/:candidateUUID/notes |
/v1/talent/{talentId}/activity |
| Log Email Activity Log email communication as an activity note with Mailgun tracking |
POST /api/unity/candidates/:candidateUUID/notes |
/v1/talent/{talentId}/activity |
| Operation | Endpoint | ATS Op |
|---|---|---|
| Search Candidates (Weighted) Hybrid candidate search: GLYDE candidate indexes fused with a live-ATS leg via Reciprocal Rank Fusion |
POST /api/unity/search/searchCandidates |
searchCandidatesWeighted (index + QueryMultiple hydration) |
| Search Jobs (Weighted) Semantic + structured job search over jobs-index fused with live ATS results |
POST /api/unity/search/searchJobs |
searchJobsWeighted (jobs-index + live leg) |
| Raw Index Query (aiSearchIndex) Direct Azure AI Search query against any GLYDE index (candidates, jobs, companies, contacts) with OData filters, facets, highlighting, and semantic ranking |
POST /api/unity/search/aiSearchIndex |
Azure AI Search (5 GLYDE indexes) |
| 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) |
| Job Application Analytics Aggregate applicant counts and positive/negative/pending ratios per job from the enriched jobs index |
POST /api/unity/search/jobApplicationAnalytics |
jobs-index candidates_by_result buckets |
| ATS Proxy (Discovery & Execute) Direct execution of any of the 270 Avionté operations exposed in the cleaned OpenAPI spec — includes QueryMultipleTalents, QueryMultipleJobs, and picklist lookups, but no search/filter operation |
POST /api/unity/proxy/avionte/:operationId |
Any spec operationId (e.g. QueryMultipleTalents) |
| Operation | Endpoint | ATS Op |
|---|---|---|
| Conversations List The recruiter-facing list of active applicants (Buddy Conversations tab) — merged view of GLYDE-native and ATS-cached candidates |
POST /api/unity/conversations/list |
unityGetConversationsList (cross-index merge) |
| Conversations Search Filter/search within the conversations view |
POST /api/unity/conversations/search |
unitySearchConversations (cross-index merge) |
| Candidate Conversation History Full message/activity history for one conversation (GLYDE database) |
POST /api/unity/conversations/history |
unityGetCandidateHistory (MySQL) |
| Operation | Endpoint | ATS Op |
|---|---|---|
| Read Tenant Configuration Self-describing read of every documented Clients.unity_configuration block with current values, defaults, and per-setting effects |
GET /api/unity/support/tenant-configuration |
getSupportTenantConfiguration (admin/internal) |
| Update Tenant Configuration Partial, row-locked, audited patch of documented configuration blocks (search, pii_policy, event_system, ats_status_screen_result_mapping, …) |
POST /api/unity/support/tenant-configuration |
updateSupportTenantConfiguration (admin/internal only) |
| Import Directory Rows Seed/repair the company & contact directory indexes from customer-supplied lists during onboarding |
POST /api/unity/directory/ingest |
unityIngestDirectoryData (shared with recruiter toolset) |
| Activation Status & Verify Inspect and re-verify the tenant activation state machine (provisioned → credentials_active → mappings_seeded → events_verified → live) |
GET/POST /api/unity/activation/status + /api/unity/activation/verify |
unityGetActivationStatus / unityVerifyActivationPhase (admin/internal) |
| Seed Field Mappings / Go-Live Seed ats_mapping_overrides from the connector base profile, run the initial index sweep, and clear the activation gate |
POST /api/unity/activation/mappings/seed + /api/unity/activation/go-live + /api/unity/activation/gate |
unitySeedFieldMappings / unityStartGoLive / unitySetClientActivationGate (admin/internal) |
| Event Maintenance Platform webhook health pass: probe stale outbound destinations, auto-disable sustained failures, purge expired event logs |
POST /api/unity/events/maintenance/run |
runEventMaintenance (admin/internal; dry_run preview first) |
| Operation | Endpoint | ATS Op |
|---|---|---|
| Receive Event Webhook Inbound Avionté webhook ingestion with tenant resolution and canonical normalization |
POST /api/unity/events/webhook/avionte |
Connector-owned normalizer (AvionteEventNormalizer) |
| Query Event Log List processed events for the tenant with type/entity/status filters |
GET /api/unity/events/log |
GLYDE event store |
| Operation | Endpoint | ATS Op |
|---|---|---|
| Register Trigger Subscription Register a Power Automate callback URL as an event destination |
POST /api/unity/events/power-automate/subscriptions/register |
Event dispatch |
| Sync Default Subscriptions Provision connector default event subscriptions in GLYDE and the ATS |
POST /api/unity/events/defaults/sync |
Subscription provisioning |
| List App Notifications Event-derived in-app notifications for the tenant |
GET /api/unity/events/notifications |
Event store |
| Operation | Endpoint | ATS Op |
|---|---|---|
| Discover Operations List all available Avionté API operations with schemas and metadata |
GET /api/unity/proxy/discover/avionte |
OpenAPI spec introspection |
| Execute Operation Execute any discovered Avionté operation dynamically |
POST /api/unity/proxy/avionte/:operationId |
Dynamic (per operationId) |
| Entity Metadata Get field-level metadata for an Avionté entity type |
GET /api/unity/proxy/meta/avionte/:entity |
OpenAPI schema introspection |
| Operation | Endpoint | ATS Op |
|---|---|---|
| Request Dock Registration Send an OTP to register the GLYDE Dock for Avionté for ATS cache sync |
POST /api/unity/ats/search-cache/request-extension-registration |
OTP delivery (email or SMS) |
| Complete Dock Registration Verify OTP and issue a Dock-scoped publishable key |
POST /api/unity/ats/search-cache/complete-extension-registration |
OTP verification |
| Enqueue Cache Candidates Queue talent IDs harvested from myavionte.com for ATS search cache refresh |
POST /api/unity/ats/search-cache/enqueue-candidates |
BullMQ + Azure AI Search indexing |
Platform Access
GLYDE Unity provides unified access to AviontéBOLD across multiple Microsoft 365 and developer platforms.
Access Avionté data through the GLYDE Unity bot in Teams channels and chats.
Access: Teams Bot Framework → GLYDEBuddy Proxy → Unity REST API → Avionté Adaptor
- Search candidates and jobs via conversational AI
- View candidate profiles and application status
- Send emails with automatic Avionté activity logging
- Create and update talent records
- Paste Avionté record URLs — the bot parses myavionte.com links and resolves the underlying talent/job/placement
- Receive notifications for ATS events
Use natural language to interact with Avionté data through the GLYDE Copilot declarative agent.
Access: Copilot Agent → MCP Bridge (GLYDEBuddy) → Unity REST API → Avionté Adaptor
- Natural language queries ("Find Java developers in Chicago")
- AI-powered candidate matching and ranking
- Multi-step workflows (search → review → contact)
- ATS proxy operations for advanced queries (discover → inspect → execute)
- Entity aliasing resolves GLYDE terms to Avionté vocabulary (candidate → Talent) via atsProfile
- Connector capability gaps handled gracefully (501 entity-metadata fallbacks to atsProfile entities)
Automate Avionté workflows using the GLYDE Unity Power Platform connector.
Access: Power Platform Connector → Unity REST API → Avionté Adaptor
- Trigger flows on Avionté events (candidate.updated, application.submitted, job.created, company.updated, contact.created, etc.) via event subscriptions
- Dynamic company → contact lookup dropdowns from the GLYDE directory (searchCompanies/searchContacts + picker options) in any flow
- Create candidates from forms or external sources
- Sync data between Avionté and other business systems
- Build custom Power Apps for recruiter workflows
- Schedule bulk operations and reports
The GLYDE Dock for Avionté browser companion (Chrome MV3) keeps the GLYDE search index fresh while recruiters work in myavionte.com — smart background caching with zero clicks.
Access: Content Script (myavionte.com) → Service Worker (batching) → Unity enqueue workflow (direct) → BullMQ → Azure AI Search
- Detects talent IDs from myavionte.com URLs (
#/applicant/{id},#!/talent/{id}), search-grid links, anddata-talent-id-style attributes via a MutationObserver - Batches up to 25 talent IDs with a 2-minute flush window, deduplicated
- Feeds the ATS search-cache queue for automatic index refresh and enrichment (see Smart Background Indexing)
- One-time OTP registration issues a Dock-scoped publishable key limited to
*.myavionte.com - Avionté-only by design — the classic GLYDE Dock and the Buddy Chrome Extension never read or cache ATS data
The support persona diagnoses and operates this integration: it reads tenant configuration with documented effects, changes indexing settings, seeds field mappings, imports company lists, and runs go-live — always read-first and broker-enforced read-only outside an explicit write allowlist.
Access: Support Agent → Brokered Unity Workflows (named support tools) → Avionté Adaptor (discover/inspect only — never executes ATS operations)
- Explains "why is search empty" from live configuration values (event_system.processing flags, enrichment settings)
- Patches documented unity_configuration blocks (admin/internal callers only, audited)
- Seeds ats_mapping_overrides and runs the initial index sweep at go-live
- Parses and imports customer company/contact lists into the directory indexes (dry-run first)
- Runs webhook health maintenance (dry-run preview, then confirmed)
Programmatic access via the @glydeunity/glyde-api-client npm package.
Access: SDK Client → Unity REST API → Avionté 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
AI agents and LLMs access Avionté operations through the MCP interface.
Access: MCP Client → Unity MCP Endpoints → Workflow Handlers → Avionté 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
Voice-based interaction with Avionté data for candidate screening and discovery (ATS-agnostic).
Access: Voice SDK → Unity Voice API → Deepgram → Function Execution → Avionté Adaptor
- Voice-powered candidate screening interviews
- Job discovery and application via voice
- Real-time candidate creation during conversations
- OTP verification for candidate identity
- Context-aware conversation modes (screening, discovery, application)
Smart Background Indexing & Enrichment
Avionté exposes no search or filter API for talent, jobs, companies, or contacts — so GLYDE Unity maintains its own Azure AI Search indexes and keeps them current automatically. This section explains the five indexes, what feeds them, what enrichment is layered on, and which settings control it. All search capabilities in the table above run against these indexes, not against Avionté directly.
The five GLYDE indexes
| Index | Contents | Kept current by |
|---|---|---|
candidate-application-index | GLYDE-native candidates + applications (MySQL view vw_candidate_application_search) | Azure indexer, 5-minute schedule (plus on-demand runs, below) |
ats-cache-candidate-application-index | ATS-cached Avionté talent profiles with full application history and enrichment | The smart background indexing pipeline on this page |
jobs-index | Jobs from GLYDE and native Avionté jobs (webhook write-through), with applicant-count buckets | MySQL indexer (5-minute) + event write-through + enrichment |
ats-cache-company-index | Avionté company/client directory | company_* webhooks, job-event seeding, imports |
ats-cache-contact-index | Avionté contact directory with denormalized company refs | contact_* webhooks, job-event seeding, imports |
The recruiter Conversations list is not a sixth index — it is a query-time merge of the two
candidate indexes, deduplicated by candidate_uuid (details below). Use
unityInspectGLYDEIndexSchema to discover every field per index.
What feeds the index
Triggers. The atsSearchCache BullMQ queue is fed by four producers:
- GLYDE Dock for Avionté — talent IDs harvested while recruiters browse myavionte.com (batches of ≤25, 2-minute flush, 15-minute per-ID dedup).
- Avionté webhooks —
talent_updated, application-lifecycle events (talent_applied_for_job,talent_submitted,talent_stage_updated, pipeline and nomination events), and job/company/contact events. Gated per tenant byevent_system.processing.update_ats_cache(default on). - Live-read write-back — candidates returned by any live ATS read (search legs, get-by-id) are enqueued so the cache stays warm; job events write through to
jobs-indexdirectly. - Go-live sweep — the activation go-live enqueues the initial population in ≤1000-ID batches.
Pipeline. Each queued talent ID is processed by a two-phase worker:
(1) cache phase — fetch the profile live from Avionté (QueryMultipleTalents; never re-read from the index, which previously caused data degradation), map it through CandidateDataMapper into the canonical index schema, resolve the GLYDE UUID via ExternalMappings (email-match reuse before minting new UUIDs), and run enrichment (below);
(2) indexing phase — a second worker sanitizes application sub-documents, hydrates missing job_titles from jobs-index, and merge-uploads the document into ats-cache-candidate-application-index.
Reliability. Retryable failures (auth in progress, HTTP 429/5xx, timeouts) are retried with exponential backoff (3 attempts); a 15-minute enqueue-dedup window prevents feedback loops; empty profile stubs (IDs that are not real candidates) are skipped rather than indexed as noise.
Candidate enrichment — what the cache adds on top of the ATS record
Every indexed talent document carries more than the raw Avionté profile:
- Applications (three live tiers + two backfills): web-applicant portal rows → job-scoped talent stages → (paced sequentially, 429s retried). On top of the live list, manual-progress reconcile folds GLYDE-recorded application progress (MySQL) into the list, and pipeline backfill folds
job_pipeline_talent_*webhook events in as synthetic applications (Avionté has no pipeline-list API). Job titles and worksite details are hydrated fromjobs-index, and every application first seen against an unknown job triggers a bounded jobs-index backfill (≤8 jobs per pass) so titles resolve. - Screen results: raw ATS statuses are translated to GLYDE positive/negative/pending semantics via
ats_status_screen_result_mapping(tenant-overrideable, sensible per-ATS defaults). - Chat summaries: recent ATS activity notes folded in as summaries when
ats_cache_chat_summary_notesis configured (filterable by action type and date). - Hotlists, ownership, metadata:
member_of_hotlists, recruiter/owner resolution to GLYDE users,ats_metadata[](standardized snake_case fields:last_job_title,last_employer,skills,experience_years, …) and the unmapped remainder underats_raw_data(capped).
Jobs index: write-through + application enrichment
Write-through. job_created/job_updated webhooks (including job aggregate mutations — posts, skills, VMS) hydrate the full job via QueryMultipleJobs and write it to jobs-index with a deterministic job UUID — so native Avionté jobs are searchable, not just jobs created through GLYDE. Every indexed job also seeds its companyId/contactId into the directory indexes.
Application enrichment (opt-in). With search.enrich_jobs_index_applications: true, each ingested job is additionally enriched with its applicant list: applications are fetched, resolved to GLYDE candidate UUIDs, bucketed into candidates_by_result.{positive|negative|pending} (cap 500 per bucket), and the job's last_modified is bumped. The discovered applicants are fanned back into the candidate cache for their own enrichment. This powers the jobApplicationAnalytics workflow and job-level dashboards.
Note on gates: this flag is opt-in and ships dark — it takes effect only when the platform-side kill switch GLYDE_JOBS_INDEX_APPLICATION_ENRICHMENT=1 is also enabled for the environment. Both gates must be on.
Company & contact directory indexing
The directory indexes populate themselves from company_* and contact_* webhooks: the event worker hydrates the full record from Avionté (QueryMultipleCompanies/QueryMultipleContacts) and indexes it. Job events contribute seed rows for the job's company/contact. Coverage is therefore event-seeded, not a full ATS mirror — zero hits never means the ATS has no such company. Two ways to fill gaps:
- Import (
/api/unity/directory/ingest, or the Support Agent): parsed rows are merged withorigin: import; rows carrying a real ATS id never shadow webhook-hydrated records, and rows without one get stable synthetic keys so re-imports update in place. - Live reads via the ATS proxy (
CompanyIdsenumeration +QueryMultipleCompanieshydration) for ad-hoc lookups.
Conversations list freshness
The recruiter Conversations list (active applicants) merges the two candidate indexes, so it updates when either side changes. GLYDE-native changes land via the 5-minute MySQL indexer; ATS-side changes land via the smart cache pipeline above. On top of both, conversation-affecting events (any application.*, screen.*, glyde_screen.*, inbound SMS/email) trigger a debounced on-demand indexer run: the Azure indexer is invoked immediately (2-second debounce), awaited to completion, and a platform.conversation_index_refreshed tick is pushed to the GLYDE web app, which streams a refresh event to that tenant's connected clients (Teams tab, side panel, web) so lists update within seconds instead of waiting for the 5-minute schedule.
Indexing settings your tenant controls
| Setting (Clients.unity_configuration) | Default | Effect |
|---|---|---|
event_system.processing.update_ats_cache | true | Webhook events refresh the candidate cache. If false the tenant appears "live but empty" — the classic misconfiguration. |
search.enrich_jobs_index_applications | false | Jobs-index applicant buckets + analytics (also requires the platform env kill switch; see above). |
ats_status_screen_result_mapping | per-ATS defaults | Maps raw Avionté status substrings to positive/negative screen results in the index. |
ats_cache_chat_summary_notes | off | Which ATS activity notes (action types, date window, limit) are folded into indexed chat summaries. |
find_defaults.staleness_ms | 24h | Age after which an index document is considered stale and find/get falls back to live ATS enrichment. |
communication_writeback.enabled | true | Mirrors sent SMS/email to Avionté as talent activity notes (write-back queue). |
Entity Mappings
AviontéBOLD uses different entity names and field conventions. GLYDE Unity normalizes these through the index-centric data pipeline.
Candidate → Talent
| Unity Field | AviontéBOLD Field | Direction | Notes |
|---|---|---|---|
first_name |
firstName |
Bidirectional | Required |
last_name |
lastName |
Bidirectional | Required |
email |
email |
Bidirectional | Required, used for deduplication |
phone |
phone |
Bidirectional | — |
address |
address.street |
Bidirectional | — |
city |
address.city |
Bidirectional | — |
state |
address.state |
Bidirectional | — |
zip |
address.zipCode |
Bidirectional | — |
candidate_uuid |
id (via ExternalMapping) |
Read | Mapped through GLYDE ExternalMapping table |
ats_metadata[].last_job_title |
lastJobTitle |
Read | Canonical index enrichment — standardized snake_case fields in the ats_metadata collection |
ats_metadata[].last_employer |
lastEmployer |
Read | Index enrichment |
ats_metadata[].skills |
skills |
Read | Index enrichment; searchable |
ats_metadata[].experience_years |
experienceYears |
Read | Index enrichment |
ats_raw_data |
(unmapped remainder) |
Read | Vendor fields not in the standard map are preserved verbatim (size-capped) for proxy parity |
applications[].ats_application_id |
webApplicant / pipeline id |
Read | Enriched application collection on the index document |
applications[].job_title / ats_status / screen_result |
job title + status (translated) |
Read | Title hydrated from jobs-index; status mapped via ats_status_screen_result_mapping |
applications[].recruiter_uuid |
owner/recruiter (resolved) |
Read | Resolved to GLYDE users via ExternalMappings |
Job → Job
| Unity Field | AviontéBOLD Field | Direction | Notes |
|---|---|---|---|
title |
title |
Bidirectional | — |
description |
description |
Bidirectional | — |
status |
status |
Bidirectional | Default: "Open" |
category |
department |
Bidirectional | — |
employment_type |
jobType |
Bidirectional | — |
salary_min / salary_max |
salary.min / salary.max |
Bidirectional | Parsed as float, currency: USD |
address + city + state |
location |
Write | Concatenated on write |
Application → Application
| Unity Field | AviontéBOLD Field | Direction | Notes |
|---|---|---|---|
application_uuid |
id |
Read | — |
candidate_uuid |
talentId |
Write | — |
job_uuid |
jobId |
Write | — |
Placement → Assignment
| Unity Field | AviontéBOLD Field | Direction | Notes |
|---|---|---|---|
placement_uuid |
id |
Read | Avionté uses "Assignment" terminology |
Company (directory) → Company
| Unity Field | AviontéBOLD Field | Direction | Notes |
|---|---|---|---|
company_name |
name |
Read | Indexed into ats-cache-company-index from company_* webhooks + job-event seeding |
industry / status / location |
industry / status / addresses |
Read | Searchable directory fields (OData + free text); archived eq 0 applied by default |
ats_company_id |
id |
Read | Directory picker value; referenced by jobs and contacts |
Contact (directory) → Contact
| Unity Field | AviontéBOLD Field | Direction | Notes |
|---|---|---|---|
first_name / last_name |
firstName / lastName |
Read | Indexed into ats-cache-contact-index from contact_* webhooks |
email / phone / title |
email / phone / title |
Read | Searchable directory fields |
ats_company_id + company_name |
companyId (denormalized) |
Read | Company-scoped lookups and dependent PA dropdowns |
Endpoint Reference
| Method | Unity Endpoint | Description | ATS Operation | Auth |
|---|---|---|---|---|
POST |
/api/unity/candidates |
Create candidate (with create-or-reuse dedup) | CreateTalent |
API Key + User UUID |
GET |
/api/unity/candidates/:uuid |
Get candidate by ID (live + cache merge) | QueryMultipleTalents |
API Key + User UUID |
PUT |
/api/unity/candidates/:uuid |
Update candidate | UpdateTalent |
API Key + User UUID |
POST |
/api/unity/jobs |
Create job | CreateJob |
API Key + User UUID |
PUT |
/api/unity/jobs/:uuid |
Update job (UpdateJob; jobId routed to spec path param) | UpdateJob |
API Key + User UUID |
POST |
/api/unity/applications |
Create application (CreateWebApplicant) | CreateWebApplicant |
API Key + User UUID |
GET |
/api/unity/applications/:uuid |
Get application | getApplication |
API Key + User UUID |
POST |
/api/unity/applications/find |
Find applications by candidate/job filter | GetTalentStagesForJob |
API Key + User UUID |
POST |
/api/unity/applications/job/latest |
Get applications for a job | GetWebApplicantsForJob |
API Key + User UUID |
POST |
/api/unity/activities |
Create activity — note or task (unified workflow) | CreateTalentActivity |
API Key + User UUID |
POST |
/api/unity/candidates/:uuid/notes |
Add candidate note (legacy) | /v1/talent/{id}/activity |
API Key + User UUID |
POST |
/api/unity/messages/send-email |
Send email + log activity | Mailgun + Activity API |
API Key + User UUID |
POST |
/api/unity/sms/send |
Send SMS (Twilio; mirrored to Avionté as an activity note via the communication write-back queue) | Twilio + CreateTalentActivity |
API Key + User UUID |
POST |
/api/unity/search/conversationalAISearch |
AI-powered search | Azure AI Search |
API Key + User UUID |
POST |
/api/unity/search/searchCandidates |
Weighted candidate search (index legs + live leg, RRF fusion; long fields via include_fields) | searchCandidatesWeighted |
API Key + User UUID |
POST |
/api/unity/search/searchJobs |
Weighted job search over jobs-index + live leg (archived eq 0 by default) | searchJobsWeighted |
API Key + User UUID |
POST |
/api/unity/search/jobApplicationAnalytics |
Applicant counts and result ratios per job (enriched jobs index) | getJobApplicationAnalytics |
API Key + User UUID |
POST |
/api/unity/conversations/list |
Conversations list of active applicants (cross-index merge; event-refreshed) | unityGetConversationsList |
API Key + User UUID |
POST |
/api/unity/conversations/search |
Search within the conversations view | unitySearchConversations |
API Key + User UUID |
POST |
/api/unity/conversations/history |
Message/activity history for one conversation | unityGetCandidateHistory |
API Key + User UUID |
GET |
/api/unity/connector-usage |
Connector API usage rollup (1/7/30 days; what this integration called on Avionté) | unityInspectConnectorUsage |
API Key + User UUID |
GET |
/api/unity/support/tenant-configuration |
Read documented tenant configuration blocks with effects (support surface) | getSupportTenantConfiguration |
API Key + User UUID (admin/internal) |
POST |
/api/unity/support/tenant-configuration |
Patch configuration blocks (search, pii_policy, event_system, …) | updateSupportTenantConfiguration |
API Key + User UUID (admin/internal) |
GET |
/api/unity/activation/status |
Activation state machine status (credentials/mappings/events/live) | unityGetActivationStatus |
API Key + User UUID (admin/internal) |
POST |
/api/unity/events/maintenance/run |
Webhook health maintenance pass (dry-run first) | runEventMaintenance |
API Key + User UUID (admin/internal) |
POST |
/api/unity/search/searchCompanies |
Search the event-fed company/client directory (name, industry, status, location) | ats-cache-company-index |
API Key + User UUID |
POST |
/api/unity/search/searchContacts |
Search the contact directory with denormalized company refs | ats-cache-contact-index |
API Key + User UUID |
POST |
/api/unity/directory/companyOptions |
Company picker options for dynamic lookup (value = ats_company_id) | Directory index |
API Key + User UUID |
POST |
/api/unity/directory/contactOptions |
Contact picker options, optionally company-scoped (value = ats_contact_id) | Directory index |
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/events/webhook/avionte |
Inbound Avionté webhook ingestion | AvionteEventNormalizer |
Public (tenant resolved from payload) |
GET |
/api/unity/events/log |
Query tenant event log | Event store |
API Key + User UUID |
POST |
/api/unity/events/power-automate/subscriptions/register |
Register Power Automate event destination | Event dispatch |
API Key + User UUID (admin) |
POST |
/api/unity/events/defaults/sync |
Sync default event subscriptions | Subscription provisioning |
API Key + User UUID (admin) |
GET |
/api/unity/proxy/discover/avionte |
Discover ATS operations | OpenAPI introspection |
API Key + User UUID |
POST |
/api/unity/proxy/avionte/:opId |
Execute any of 270 Avionté spec operations (no search op exists; use QueryMultipleTalents/QueryMultipleJobs batch reads) | Dynamic |
API Key + User UUID |
GET |
/api/unity/proxy/meta/avionte/:entity |
Get entity metadata | Schema introspection |
API Key + User UUID |
POST |
/api/unity/ats/search-cache/request-extension-registration |
Request extension registration OTP | OTP delivery |
Publishable/Scoped Key |
POST |
/api/unity/ats/search-cache/complete-extension-registration |
Verify OTP, issue extension key | OTP verification |
Scoped |
POST |
/api/unity/ats/search-cache/enqueue-candidates |
Enqueue candidate IDs for cache refresh | BullMQ + Azure AI Search |
Extension Publishable Key |
Events & Webhooks
Avionté inbound webhook processing is live and connector-owned.
Inbound webhooks are received at POST /api/unity/events/webhook/avionte, the tenant is
resolved from FrontOfficeTenantId via ExternalMappings, and events are normalized
to the canonical GLYDE format by AvionteEventNormalizer before entering the event queue.
Beyond delivery to subscribers, each event family triggers automatic indexing actions
inside GLYDE (the Automatic Actions column below) — this is what keeps the search indexes
current as Avionté records change. Outbound forwarding to Power Automate, Make.com, webhooks, and
in-app notifications is configured per tenant through event subscriptions (see
Forwarding & Filtering below).
| Event | Trigger | Payload | Automatic Actions |
|---|---|---|---|
candidate.updated |
talent_updated — an Avionté talent record changes | Talent ID, changed resource fields | Candidate cache refresh: live profile + applications re-fetched, enriched, and re-indexed (gated by event_system.processing.update_ats_cache) |
application.applied |
talent_applied_for_job — a talent applies to a job | Talent ID, Job ID, application resource | Candidate cache refresh + conversations list refresh (debounced on-demand indexer run + live UI tick) + durable ATS activity row |
application.updated |
talent_application_modified — an application record is modified | Application ID, changed fields | Candidate cache refresh + conversations list refresh + ATS activity row capture |
application.submitted |
talent_submitted — a talent is submitted to a job | Talent ID, Job ID | Candidate cache refresh + conversations list refresh + ATS activity row capture |
application.stage_updated |
talent_stage_updated — an application stage changes | Stage ID, Talent ID, Job ID | Candidate cache refresh (screen-result re-mapping) + conversations list refresh + ATS activity row capture |
application.pipeline_talent_added |
job_pipeline_talent_added — talent added to a job pipeline | Talent ID, Job Pipeline ID | Candidate cache refresh + pipeline backfill source (synthetic application entries) + conversations refresh |
application.pipeline_talent_updated |
job_pipeline_talent_updated — pipeline talent record changes | Talent ID, Job Pipeline ID, changed fields | Candidate cache refresh + pipeline backfill source + conversations refresh |
job.updated |
job_updated — an Avionté job changes | Job ID, changed resource fields | Jobs-index write-through: full job hydrated via QueryMultipleJobs and merged into jobs-index; referenced company/contact seeded into the directory indexes |
job.created |
job_created — a new job is created | Job ID, job resource | Jobs-index write-through (deterministic job UUID) + directory seeding |
job.updated.{event} / job.created.vms_job_created |
job_post_created / job_post_updated / job_post_deleted / job_skills_updated — job aggregate mutations map to job.updated.{vendorEvent}; vms_job_created maps to job.created.vms_job_created. Granularity distinguishes a job POST change from the job record itself while rolling up to the job. prefix for indexing | Job ID | Same jobs-index write-through as job.updated (prefix-driven) |
company.updated / company.updated.{event} |
company_updated maps to company.updated; sub-entity events (address, department, PO, tag, restriction, custom extra) map to company.updated.{vendorEvent} — granularity preserved for subscriptions, rollup prefix drives directory indexing | Company ID; the full record is re-hydrated for the company directory index | Directory sync: full company re-hydrated via QueryMultipleCompanies and indexed into ats-cache-company-index |
contact.created |
contact_created — a new contact record is created | Contact ID; hydrated into the contact directory index | Directory sync into ats-cache-contact-index (powers contact search + PA dropdowns) |
contact.updated / contact.updated.{event} |
contact_updated maps to contact.updated; contact_tag_added / contact_tag_deleted map to contact.updated.{vendorEvent} | Contact ID; hydrated into the contact directory index | Directory sync into ats-cache-contact-index |
Forwarding & Filtering
Normalized events are re-published to the destinations configured on the tenant
(Clients.unity_configuration.event_system.outbound[]). Four destination types exist:
webhook (generic HTTP callback with a camelCase envelope), power_automate and
make (flow trigger callbacks using the canonical snake_case event object, with automatic
disabling of dead triggers), and app_notification (in-app notifications).
Filtering is per destination by event type: exact names (application.submitted),
prefix wildcards (application.*, job.*), the catch-all *, or an empty
list meaning all events — there are no per-record or per-entity filters. Flow destinations register
themselves at POST /api/unity/events/power-automate/subscriptions/register (Make.com and
generic webhook variants exist alongside; GET .../trigger-options lists the available filters).
Connector defaults (inbound subscription set, processing flags, notification destinations) are provisioned
at onboarding and can be re-synced via POST /api/unity/events/defaults/sync. Delivery retries
with exponential backoff (3 attempts); failed deliveries are retained 7 days for inspection, delivery
attempts 90 days, and a daily maintenance sweep probes and auto-disables persistently failing destinations
(also available on demand via POST /api/unity/events/maintenance/run, dry-run first).
API Usage Metering
Every call GLYDE Unity makes to Avionté on your tenant's behalf is counted — both the ATS proxy operations you invoke directly and the workflow/adaptor calls made for you. Counts roll up per hour into a durable table and are exposed to tenant admins, so you can see exactly what the integration is doing against your Avionté API subscription.
What is counted
One count per connector operation invocation (internal retries count as one call), recorded on
success and failure alike along the dimensions tenant (client_uuid),
connector (avionte), operation (e.g.
QueryMultipleTalents, CreateWebApplicant), and ok/error.
Service calls to non-ATS providers (Twilio, Mailgun, Azure AI Search) are not counted. Counting is
fire-and-forget — a metering problem can never break an API call.
How it is stored
Counters accumulate in Redis per UTC hour (unity:connectors:usage:w:*, TTL 26h)
and a flusher drains closed windows every 15 minutes into the connectorcallusage MySQL
table (hourly rows with per-operation breakdown, kept indefinitely). Reading lags real time by roughly
25 minutes; the API also surfaces the in-flight current hour separately.
Where to see it
- API/SDK:
GET /api/unity/connector-usage?days=1|7|30(unityInspectConnectorUsage) — totals, errors, per-connector daily series, zero-filled. - GLYDE web app (Buddy): the Connector Usage page renders 1/7/30-day toggles and per-connector daily charts for your tenant.
- Support Agent: support can inspect usage when diagnosing "is the integration hammering the ATS" questions.
Caveats
Counts are best-effort and near-real-time, not invoicing-grade: brief windows can be lost on Redis failover, and windows older than 26h are dropped if the flusher is down for an extended period. Usage-based throttling/quotas are not enforced today.
Data Privacy & PII Masking
Tenants can control what personally identifiable information GLYDE's AI agents may see, configured
per client under Clients.unity_configuration.pii_policy. Scope matters: masking is
model-facing only — it changes what LLM-based agents process, never what the direct Unity
API returns, what Power Automate/Make flows receive, or what is stored in the ATS, GLYDE's database, or the
search indexes.
Settings
| Setting | Options / default | Effect |
|---|---|---|
enabled | false (opt-in) | Master switch for entity masking inside agent processing (email/voice/SMS agents, Teams chats, scheduled tasks — every agent role). |
entity_types | email, phone, ssn, credit_card (all four by default) | Which entity types are detected and tokenized when enabled. Detection is deliberately conservative (dashed SSNs, structured phones). |
token_format | bracketed (default) | hash | How masked values appear to the model: [[PII:email:1]] (reversible, per-conversation occurrence index) or an opaque 8-char hash. |
mask_mode | per entity: token | last4 | token = reversible placeholder (restored for display/actions). last4 = one-way partial mask (***-**-6789) that can never be restored. |
restore_on_output | true | When true the user's reply shows the original values; set false for compliance-sensitive tenants to keep replies masked. |
masked_candidate_fields | DOB/age field keys (default on) | One-way field masking independent of enabled: date-of-birth values are year-masked (****-07-06) and age-like values fully masked in agent-visible tool results. |
How it behaves end-to-end
When enabled, PII values are replaced with tokens before anything reaches the model —
user messages, recalled facts, and tool results all enter the transcript tokenized. Tokens are mapped
back to originals only at two seams: outbound actions (an SMS/email the agent sends carries real
values, swapped in at the moment of execution) and, if restore_on_output is true, the
final reply shown to the user. The token map lives only in memory for the duration of a run — never
in the database, caches, traces, or logs. last4-masked values are never restored
anywhere.
Configuring it
Admins (and the GLYDE Support Agent, via the tenant-configuration
surface) read and change pii_policy under the pii_policy configuration block;
changes take effect on the next agent run. The tenant-facing knowledge base article
(PII & Data Privacy) explains the same behavior for end users.
Onboarding & Activation
New tenants are provisioned and activated through the GLYDE onboarding wizard in the web app, backed by Unity trusted setup/activation endpoints. The wizard walks through connecting the ATS, granting permissions, mapping fields with live Avionté dropdowns, provisioning event subscriptions, and go-live — with a support-ticket approval loop before the tenant starts indexing.
Wizard steps (GLYDE web app)
- Install the GLYDE Teams app.
- Grant permissions — Microsoft Graph admin consent for the tenant.
- GLYDE account — resolve or create the account; GLYDE staff can provision a new client here (company, ATS, admin user) via the staff-provisioned client-create path.
- Optional integrations — install the GLYDE Power Automate connector (Make.com shown as coming soon).
- Connect your ATS — pick Avionté, store credentials, and sync users; the event-subscription panel lists and re-syncs the tenant's Avionté webhook subscriptions.
- Go-live readiness — phase checklist (below), Avionté configuration with live dropdowns from your own Avionté tenant (activity types, submission user), then request go-live approval (staff can enable directly).
- GLYDE Dock install (optional) and done.
Activation phases & the gate
Clients are born gated (activation pending) and move through a verified state
machine: provisioned → credentials_active → mappings_seeded → events_verified →
live. Credentials live in Azure Key Vault (never logged or echoed); field mappings are seeded
from the Avionté connector base profile into ats_mapping_overrides; default event
subscriptions are provisioned idempotently. Go-live files an approval ticket (one open request per
tenant, decided by a human or the support ticket loop) and — once approved — clears the gate and
enqueues the initial index sweep. Status and re-verification are also exposed to the Support Agent
(unityGetActivationStatus / unityVerifyActivationPhase).
Power Automate setup & dropdown mappings
Installing the GLYDE Power Platform connector from the wizard makes every Unity workflow
available as a flow action. Fields that need Avionté-specific ids render as dynamic
dropdowns instead of free text: company/contact pickers are powered by the directory indexes
(x-ms-dynamic-values against unityDiscoverCompanyDirectoryOptions /
unityDiscoverContactDirectoryOptions, dependent company → contact), and ATS-operation
schemas inject the tenant's own cached picklists (e.g. branchId) as typed enums so flow
authors never hand-copy Avionté ids. Unmapped required ATS fields surface as typed
extra_ats_fields wrappers in the designer.
Configuration Requirements
-
OAuth2 Client CredentialsREQUIRED
Avionté issues client_id and client_secret for API access. These must be stored in Azure Key Vault via the GLYDE Unity client configuration.
client_id: "glyde-integration-client" -
Tenant IdentifierREQUIRED
The Avionté tenant identifier is required for all API calls and is injected as the Tenant HTTP header. This is typically the company's Avionté instance identifier.
tenant: "acme-staffing" -
Activity Type ConfigurationREQUIRED
Client-specific activity type IDs for logging notes in Avionté. Configured in integration_data.AvionteConfiguration. Resolution order: general_activity_type, then Talent.general_activity_type (human_review uses Talent.human_review_activity_type).
AvionteConfiguration.general_activity_type: 42 -
Activity Author User IDREQUIRED
Avionté user ID used as the author for GLYDE-created activities. Resolution order: new_submission_user, then glyde_user_id, then recruiter ExternalMappings (source=avionte, type=recruiter) for the requesting GLYDE user.
AvionteConfiguration.new_submission_user: 1001 -
Human Review Activity TypeREQUIRED
Activity type ID for "Glyde Contact Requested" notes (human_review flag). Configured per-client in AvionteConfiguration.Talent.human_review_activity_type.
AvionteConfiguration.Talent.human_review_activity_type: 15 -
Webhook Subscription (Optional)
To receive live Avionté events, register the GLYDE webhook URL (
{unityBaseUrl}/api/unity/events/webhook/avionte) in the Avionté webhook configuration and ensure an ExternalMapping exists for the FrontOfficeTenantId. Default subscriptions can be provisioned viaPOST /api/unity/events/defaults/sync.Webhook URL: https://api.glydeunity.com/api/unity/events/webhook/avionte -
Chrome Extension ID (Optional)
When using the GLYDE Chrome Extension for ATS cache sync, set
UNITY_AVIONTE_EXTENSION_CHROME_IDso the extension origin is allowed to complete OTP registration and enqueue candidate IDs.UNITY_AVIONTE_EXTENSION_CHROME_ID: "abcdefghijklmnopqrstuvwxyz" -
Smart Indexing Settings (Optional)
Tenant-level switches that govern background indexing and enrichment:
event_system.processing.update_ats_cache(default true — webhook-driven cache refresh; false produces a "live but empty" tenant),search.enrich_jobs_index_applications(default false — jobs-index applicant buckets; also requires the platform-side kill switch),ats_status_screen_result_mapping(ATS status → screen result),ats_cache_chat_summary_notes(ATS notes into chat summaries), andfind_defaults.staleness_ms(index staleness threshold before live fallback). See Smart Background Indexing.search: { enrich_jobs_index_applications: true } -
PII Policy (Optional)
Per-tenant AI data-privacy posture under
pii_policy:enabled(default false),entity_types(email/phone/ssn/credit_card),token_format(bracketed/hash),mask_mode(reversible token vs one-way last4 per entity),restore_on_output, andmasked_candidate_fields(DOB/age masking, default on). Model-facing only — direct API responses and stored data are never tokenized. See Data Privacy & PII Masking.pii_policy: { enabled: true, mask_mode: { ssn: "last4" } } -
Integration TypeREQUIRED
The client's integration_type must be set to "avionte" in the GLYDE client configuration for the adaptor router to select the correct integration.
integration_type: "avionte" -
API Base URL (Optional)
Override the default AviontéBOLD API base URL if using a non-standard endpoint.
service_url: "https://api.avionte.com"
Known Limitations
- No live search API for Talent or Jobs. Avionté exposes no search/filter endpoint — GLYDE serves candidate/job search from the Azure AI Search index and uses
QueryMultipleTalents/QueryMultipleJobsbatch reads for live pulls. The connector's canonicalsearchCandidates/searchJobsmethods returnNOT_IMPLEMENTEDandatsProfile.searchCapabilities.supportedisfalse. - Candidate entity is called "Talent" in Avionté — all API operations use this naming convention.
- Placement entity is called "Assignment" in Avionté.
- Record updates use full PUT (not PATCH) — all fields must be provided on updates, not just changed fields.
- Application updates return
NOT_IMPLEMENTED— Avionté does not support direct application modifications through the current API version. - Live job get-by-id is not implemented — job reads resolve from the GLYDE search index; only create and update write through to Avionté.
- Job notes are not supported — unified activities write talent activities only (
CreateTalentActivity). Activity retrieval from Avionté is not implemented. - SMS messages and emails are mirrored to Avionté as talent activity notes (
CreateTalentActivity, subtypecommunication/email_sent) via the tenant-gated communication write-back queue (unity_configuration.communication_writeback.enabled, default on) — but only sends carrying candidate/application context; raw-recipient sends with no candidate link are not mirrored. - Job create requires Avionte
front_office__JobDtofields — map UI payload viaJobDataMapper, injectbranchId/ownerUserIdserver-side, and supply tenant Avionte ids fromAvionteConfiguration(company_id,job_status_id,job_contact_id,job_order_type_id,front_office_id,worksite_address_id) onintegration_dataand/orunity_configuration. - The Avionté OpenAPI spec uses camelCase field naming, which differs from GLYDE Unity's snake_case convention. Mapping is handled automatically.
- Entity metadata inspection may return
501from the connector for some entity types — Buddy falls back to theatsProfile.entitiescatalog with a structured "unsupported" envelope. - Pagination uses offset/limit pattern with a default limit of 25 records per page.
- The
Tenantheader is required for all API calls and is automatically injected by the connector. - Avionté deep links require the tenant
atsBaseUrl(myavionte.com subdomain) to be configured; otherwise links fall back to the GLYDE Screen /dl/ resolver. - There is no dedicated Avionté recommended-fields provider for LLM tool calls — prompts rely on
unityInspectATSOperation/unityInspectATSEntityFieldsoutput. - Jobs-index application enrichment is dual-gated: the tenant flag
search.enrich_jobs_index_applicationstakes effect only when the platform env kill switchGLYDE_JOBS_INDEX_APPLICATION_ENRICHMENT=1is also enabled — the feature ships dark by default. - Connector usage metering is best-effort — near-real-time (≈25-minute lag), small windows can be lost on Redis failover, and it is not invoicing-grade. Usage-based throttling/quotas are not enforced.
- The smart background cache ships only in the GLYDE Dock for Avionté — the classic GLYDE Dock (workspace) and the Buddy Chrome Extension (AI assistant) never read or cache ATS data, and the enqueue route is Avionté-gated.
- PII masking is model-facing only — it never tokenizes direct Unity API responses, Power Automate/Make deliveries, or data at rest in the ATS, GLYDE database, and search indexes.
Version History
- New section: Smart Background Indexing & Enrichment — the five GLYDE Azure AI Search indexes, what feeds the atsSearchCache pipeline (Dock harvest, webhooks, live-read write-back, go-live sweep), the two-phase worker, candidate enrichment (three live application tiers + manual-progress reconcile + pipeline backfill + jobs-index title backfill + chat summaries + hotlists), jobs-index write-through and opt-in application enrichment, directory indexing, conversations-list freshness (debounced on-demand indexer + live UI tick), and the tenant settings that control it all.
- New section: API Usage Metering — per-tenant/connector/operation counting of every Avionté call, Redis hourly windows flushed to the
connectorcallusagetable, and theunityInspectConnectorUsageendpoint, Buddy Connector Usage page, and caveats. - New section: Data Privacy & PII Masking — the full
pii_policyshape (enabled, entity_types, token_format, mask_mode token/last4, restore_on_output, masked_candidate_fields), the four model-facing enforcement seams, and the explicit scope boundary (direct API responses and data at rest are never tokenized). - New section: Onboarding & Activation — the web-app wizard steps, the gated activation state machine (provisioned → live) with approval-ticket go-live, and Power Automate setup including dynamic dropdown field mappings from the tenant's own Avionté picklists and directory pickers.
- Events: each event family now documents the automatic actions it triggers (cache refresh, jobs write-through, directory sync, conversations refresh, activity capture) plus a new Forwarding & Filtering block covering outbound destinations (webhook / Power Automate / Make / app notifications), event-type filters, subscription registration, retry/DLQ retention, and health maintenance.
- Capabilities: renamed and expanded the search block to Search (GLYDE Index — the ATS has none) with weighted candidate/job search, raw aiSearchIndex queries (facets, semantic, highlighting), and job application analytics; added Conversations (Active Applicants) and Support Agent (Tenant Operations) capability cards; renamed the Chrome Extension block to GLYDE Dock for Avionté (Smart Cache Sync) with refreshed registration/enqueue details.
- Entity mappings: added canonical index-enrichment fields (ats_metadata standard fields, ats_raw_data, enriched applications[] sub-document) and new Company/Contact directory mappings; endpoint reference gained 12 rows (weighted searches, analytics, conversations, connector usage, support configuration, activation, event maintenance).
- Configuration: added Smart Indexing Settings and PII Policy requirement entries; known limitations gained dual-gate enrichment, metering precision, Dock Avionté-only, and PII scope notes.
- Companies & Contacts: new directory capabilities —
searchCompanies/searchContactssearch the GLYDE-cached company/client and contact directory indexes (/api/unity/search/searchCompanies,/api/unity/search/searchContacts) with free text and/or structured OData filters,archived eq 0by default. Because Avionté exposes no company/contact search API, GLYDE maintains the searchable copy. - Automatic indexing: the directory indexes populate themselves from Avionté webhooks —
company_*andcontact_created/updatedevents hydrate the full record (QueryMultipleCompanies/QueryMultipleContacts) and index it; every indexed job also seeds itscompanyId/contactId. Coverage is event-seeded, not a full ATS mirror — zero hits do not mean the ATS has no such record. - Jobs: the jobs search index is now auto-populated for native Avionté jobs too —
job_created/job_updatedwebhooks (and job aggregate mutations: posts, skills, VMS) hydrate viaQueryMultipleJobsand write through with deterministic job UUIDs; previously only jobs created through GLYDE were indexed. - Events: the webhook normalizer now maps ~40 event types across talent, job, company, and contact families (was 9); sub-entity mutations keep vendor granularity under rollup prefixes (
job.updated.job_post_created,company.updated.company_address_created) so webhook subscriptions can distinguish a job POST change from the job record while indexing pipelines key off the prefix; tenant resolution matches the numericFrontOfficeTenantIdagainst atype=clientExternalMapping. New event types must be added to the tenant's subscription by the Avionté Client Manager. - Dynamic lookup (Power Automate / Make.com):
unityDiscoverCompanyDirectoryOptionsandunityDiscoverContactDirectoryOptionsprovide value/label pickers with dependent company → contact dropdowns (x-ms-dynamic-values); Make.com exposes the same operations through its dynamic Unity module. - Import:
unityIngestDirectoryData(/api/unity/directory/ingest) merges parsed company/contact rows from any source format (CSV, TSV, pasted text, Excel copied as text — the calling model converts the source into structured rows); imported rows are taggedorigin: import, dry-run returns per-row validation errors. - Endpoint reference: added the five directory endpoints (searchCompanies, searchContacts, companyOptions, contactOptions, ingest).
- Messages: corrected the stale "no Avionté activity log for SMS" limitation — outbound SMS (and emails) do create Avionté activity notes via the tenant-gated communication write-back queue (
CreateTalentActivity). Mirroring requires candidate/application context and an ExternalMappings row for the candidate; raw-recipient sends without a candidate link are not mirrored.
- Rate limiting: transient HTTP 429 responses from any Avionté call (including
GetTalentStagesForJobstage fetches) are now retried with exponential backoff in the shared connector layer, honouringRetry-Afterwhen present. All-stages-failed still triggers the BullMQ retry path.
- Product Demos: added a demo video carousel after the overview — six clips (Teams install, multi-channel, comms + ATS logging, Buddy search agent, spreadsheets + Chrome, schedule agent) hosted on the GLYDE web app and rendered from the shared template for any ATS guide.
- Capabilities: added a two-layer API explainer at the top of the section — GLYDE Unity workflow endpoints (ATS-agnostic, orchestrated, normalized) vs. Avionté proxied calls (raw spec operations via
/api/unity/proxy/avionte/:operationId, vendor-native payloads) — plus a status-badge legend defining whatfull,partial,proxy only, andnot supportedsignify (rendered from the shared template for all ATS guides).
- Overview: added contractual note — AviontéBOLD API subscription + MOU required; integration is invisible to end users (hidden APIs, no marketplace tiles); client is responsible for notifying AviontéBOLD to turn the integration off.
- Events & Webhooks: inbound webhook processing is live — 9 Avionté event types normalized by the connector-owned
AvionteEventNormalizerat/api/unity/events/webhook/avionte; outbound Power Automate trigger subscriptions documented. - Capabilities: corrected candidate operations to actual spec operations (
CreateTalent,QueryMultipleTalents,UpdateTalent); create-or-reuse dedup is 409-driven (no proactive search — Avionté has no search API); connector canonicalsearchCandidates/searchJobsnow returnNOT_IMPLEMENTEDandsearchCapabilities.supportedisfalse. - Jobs: documented that live get-by-id is not implemented (index-only reads) and fixed the job update operation id casing (
updateJob→ specUpdateJob). - Applications: documented the three-tier list-by-candidate fetch (
GetWebApplicationsForTalent→GetTalentStagesForJob→GetTalentStagesForTalentByJobId) and the job-scopedfindoperation at/api/unity/applications/find. - Messages: added SMS via Twilio (
/api/unity/sms/send) — no Avionté activity log for SMS. - Chrome Extension: documented the Avionté detector + ATS cache sync flow (OTP registration → scoped publishable key → enqueue up to 25 candidate IDs) and Avionté deep-link URL templates.
- Platform Access: added Chrome Extension platform card; enriched Teams (myavionte.com URL parsing), Copilot (entity aliasing + 501 fallbacks), and Power Automate (event trigger subscriptions) capabilities.
- Known Limitations: removed stale stub-only webhook entry; added job get-by-id, job-notes, SMS activity-log, entity-metadata 501 fallback, deep-link baseUrl, and recommended-fields provider notes.
- Applications: added job-scoped web applicant retrieval through
unityGetJobApplicationsLatest, backed byGetWebApplicantsForJobwith server-sidejobIdparameter handling.
- Jobs: create job reads tenant Avionte ids from
AvionteConfigurationsnake_case keys (company_id,job_status_id, etc.) onintegration_data/unity_configuration, mapped to JobDto camelCase beforeCreateJob.
- Jobs: create job uses
JobDataMapper+ AviontesubmitFieldMapforfront_office__JobDto; tenant Avionte ids come fromunity_configuration;branchIdandownerUserIdare injected from user context.
- Jobs: create job adaptor now calls the cleaned Avionté OpenAPI operation ID
CreateJobinstead of the non-existent lowercasecreateJob.
- Empty Tier-1 detection: Avionté returns
isn't a web applicant(contraction); phrase matching updated so production no longer warns on this expected 404.
- Applications:
getWebApplicationsForTalentHTTP 404 with “not a web applicant” is treated as empty Tier 1 (success with no rows), not an API error. - Base connector: expected Tier-1 empty responses log at debug instead of warn to reduce production noise.
- Initial integration guide creation
- Documented OAuth2 client credentials authentication flow
- Documented candidate CRUD operations with index-centric data mapping
- Documented job and application operations
- Documented email messaging with Avionté activity logging
- Documented activity/note creation with configurable activity types
- Documented ATS proxy discovery and dynamic operation execution
- Documented platform access patterns (Teams, Copilot, Power Platform, SDK, MCP, Voice)
- Documented entity mappings (Talent, Job, Application, Assignment)
- Documented configuration requirements and known limitations