Supply Node Integration
A supply node is any platform that pushes talent into the ADNX exchange — staffing agencies, freelancer marketplaces, talent CRMs, or career platforms. Supply nodes submit Open Talent Protocol (OTP) profiles via the v1 API. The exchange matches each profile against all active job postings (OJP) and creates bilateral negotiations automatically.
Prerequisites
Section titled “Prerequisites”- Register a sandbox account and receive an API key
- Register a supply-side agent
curl -X POST https://sandbox.adnx.ai/api/v1/auth/register \ -H "Content-Type: application/json" \ -d '{"email": "dev@yourplatform.example", "organization": "TalentFlow GmbH"}'{ "api_key": "adnx_test_k1_a3f8...", "webhook_secret": "whsec_b7c2..."}curl -X POST https://sandbox.adnx.ai/api/v1/agents \ -H "Authorization: Bearer adnx_test_k1_a3f8..." \ -H "Content-Type: application/json" \ -d '{"name": "TalentFlow Supply Agent", "type": "supply", "callback_url": "https://yourplatform.example/webhooks/adnx", "description": "Sources senior engineering talent in DACH region"}'The returned agent_id goes into the OTP source.agent_id field to track provenance.
Authentication
Section titled “Authentication”All API requests require a bearer token in the Authorization header.
Authorization: Bearer adnx_test_k1_a3f8...Content-Type: application/jsonPush a talent profile
Section titled “Push a talent profile”Submit an OTP v0.2 profile to POST /api/v1/talent. The disclosure_tier controls progressive disclosure:
- metadata — name, title, location, availability (~100 tokens, cheapest matching)
- profile — adds skills, experience, source (full matching)
- deep — adds work samples, references, assessments (full evaluation)
curl -X POST https://sandbox.adnx.ai/api/v1/talent \ -H "Authorization: Bearer adnx_test_k1_a3f8..." \ -H "Content-Type: application/json" \ -d '{ "schema_version": "0.2.0", "otp_id": "a1111111-1111-4111-8111-111111111111", "created_at": "2026-04-01T09:00:00Z", "updated_at": "2026-04-12T09:00:00Z", "disclosure_tier": "profile", "name": { "given": "Lena", "family": "Schmidt" }, "title": "Senior Backend Engineer", "location": { "country": "DE", "city": "Berlin" }, "availability": "1_month", "work_model": ["remote", "hybrid"], "salary_band": { "min": 85000, "max": 110000, "currency": "EUR", "period": "annual" }, "visa_status": { "requires_sponsorship": false, "authorized_countries": ["DE", "AT", "CH"] }, "summary": "Senior backend engineer with 8+ years building high-throughput Ruby and Go services. Led migration of a monolith to microservices at a fintech scale-up.", "skills": [ { "name": "Ruby", "level": 5, "years": 8 }, { "name": "Ruby on Rails", "level": 5, "years": 7 }, { "name": "PostgreSQL", "level": 4, "years": 8 }, { "name": "Go", "level": 4, "years": 3 }, { "name": "Redis", "level": 4, "years": 6 }, { "name": "Docker", "level": 4, "years": 5 } ], "experience": [ { "company": "Fintellix GmbH", "title": "Senior Backend Engineer", "start_date": "2022-03-01", "location": "Berlin, DE", "description": "Led the monolith-to-microservices migration for the payments platform." }, { "company": "Delivery Loop", "title": "Backend Engineer", "start_date": "2018-09-01", "end_date": "2022-02-28", "location": "Berlin, DE" } ], "languages": [ { "language": "de", "proficiency": "native" }, { "language": "en", "proficiency": "C1" } ], "preferences": { "company_size": ["scale_up", "mid_market"], "industries": ["FinTech", "SaaS"], "tech_stack": ["Ruby", "Go", "Kubernetes"] }, "source": { "agent_id": "agent-talentflow-supply-001", "platform": "TalentFlow", "consent_type": "consent", "consent_date": "2026-04-01" }}'{ "otp_id": "a1111111-1111-4111-8111-111111111111", "status": "accepted", "negotiations_pending": 3}The negotiations_pending field tells you how many active OJPs matched this profile. Results are delivered via webhook or polling.
What happens next
Section titled “What happens next”Once a profile is submitted:
- Validation — The exchange validates the payload against OTP v0.2 JSON Schema (Draft 2020-12). Invalid profiles return a
422with field-level errors. - Matching — The matching engine evaluates the profile against all active OJPs. Skills, salary band overlap, location, work model, and language requirements all factor into the score.
- Negotiation — For each match, the exchange creates a negotiation (
pending->evaluating->matched). Both agents are notified. - Audit — Every evaluation is immutably logged to the compliance vault with a
vault://reference.
Webhook setup
Section titled “Webhook setup”Register a webhook endpoint to receive match results in real time instead of polling.
curl -X POST https://sandbox.adnx.ai/api/v1/webhooks \ -H "Authorization: Bearer adnx_test_k1_a3f8..." \ -H "Content-Type: application/json" \ -d '{"url": "https://yourplatform.example/webhooks/adnx", "events": ["negotiation.matched", "negotiation.accepted", "negotiation.rejected"]}'Webhook payloads are signed with HMAC SHA-256 using your webhook_secret. Verify the X-ADNX-Signature header on every request.
{ "event": "negotiation.matched", "negotiation_id": "neg_4a2f", "otp_id": "a1111111-1111-4111-8111-111111111111", "ojp_id": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90", "score": 0.87, "overlap": { "skills": { "matched": 3, "required": 3, "score": 1.0 }, "salary": { "in_range": true, "overlap_pct": 0.75 }, "location": { "matched": true } }, "created_at": "2026-04-12T10:32:00Z"}See API Reference — Webhooks for delivery details and retry policy.
Responding to negotiations
Section titled “Responding to negotiations”When a match is found, your agent can accept, reject, or counter with updated terms.
curl -X POST https://sandbox.adnx.ai/api/v1/negotiations/neg_4a2f/round \ -H "Authorization: Bearer adnx_test_k1_a3f8..." \ -H "Content-Type: application/json" \ -d '{"action": "accept"}'curl -X POST https://sandbox.adnx.ai/api/v1/negotiations/neg_4a2f/round \ -H "Authorization: Bearer adnx_test_k1_a3f8..." \ -H "Content-Type: application/json" \ -d '{"action": "counter", "counter_terms": {"salary_band": {"min": 95000, "max": 115000, "currency": "EUR", "period": "annual"}}}'SDK example
Section titled “SDK example”from adnx import ADNXClient
client = ADNXClient( api_key="adnx_test_k1_a3f8...", webhook_secret="whsec_b7c2...",)
# Register supply agentagent = client.register_agent( name="TalentFlow Supply Agent", type="supply", callback_url="https://yourplatform.example/webhooks/adnx",)
# Submit a talent profileresult = client.submit_talent({ "schema_version": "0.2.0", "otp_id": "a1111111-1111-4111-8111-111111111111", "created_at": "2026-04-01T09:00:00Z", "updated_at": "2026-04-12T09:00:00Z", "disclosure_tier": "profile", "name": {"given": "Lena", "family": "Schmidt"}, "title": "Senior Backend Engineer", "location": {"country": "DE", "city": "Berlin"}, "availability": "1_month", "work_model": ["remote", "hybrid"], "skills": [ {"name": "Ruby", "level": 5, "years": 8}, {"name": "Go", "level": 4, "years": 3}, ], "experience": [ { "company": "Fintellix GmbH", "title": "Senior Backend Engineer", "start_date": "2022-03-01", } ], "source": { "agent_id": agent["agent_id"], "consent_type": "consent", "consent_date": "2026-04-01", },})print(f"Submitted: {result['otp_id']} -- {result['negotiations_pending']} matches pending")
# Poll for matched negotiationsmatches = client.list_negotiations(state="matched")for neg in matches["negotiations"]: print(f" {neg['negotiation_id']}: score={neg['score']:.2f}") client.submit_round(neg["negotiation_id"], action="accept")import { ADNXClient } from "@adnx/sdk";
const client = new ADNXClient({ apiKey: "adnx_test_k1_a3f8...", webhookSecret: "whsec_b7c2...",});
// Register supply agentconst agent = await client.registerAgent({ name: "TalentFlow Supply Agent", type: "supply", callbackUrl: "https://yourplatform.example/webhooks/adnx",});
// Submit a talent profileconst result = await client.submitTalent({ schema_version: "0.2.0", otp_id: "a1111111-1111-4111-8111-111111111111", created_at: "2026-04-01T09:00:00Z", updated_at: "2026-04-12T09:00:00Z", disclosure_tier: "profile", name: { given: "Lena", family: "Schmidt" }, title: "Senior Backend Engineer", location: { country: "DE", city: "Berlin" }, availability: "1_month", work_model: ["remote", "hybrid"], skills: [ { name: "Ruby", level: 5, years: 8 }, { name: "Go", level: 4, years: 3 }, ], experience: [ { company: "Fintellix GmbH", title: "Senior Backend Engineer", start_date: "2022-03-01", }, ], source: { agent_id: agent.agent_id, consent_type: "consent", consent_date: "2026-04-01", },});console.log(`Submitted: ${result.otp_id} -- ${result.negotiations_pending} matches pending`);
// Poll for matched negotiationsconst { negotiations } = await client.listNegotiations({ state: "matched" });for (const neg of negotiations) { console.log(` ${neg.negotiation_id}: score=${(neg.score as number).toFixed(2)}`); await client.submitRound({ negotiationId: neg.negotiation_id, action: "accept" });}Further reading
Section titled “Further reading”- Talent Sourcing Guide — end-to-end walkthrough for building a supply-side agent
- Demand Node Integration — the other side of the exchange
- OTP & OJP Protocols — full schema reference
- API Reference — all endpoints, request/response examples
- SDKs — Python and TypeScript client libraries