Skip to content

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.


  1. Register a sandbox account and receive an API key
  2. Register a supply-side agent
1. Register for sandbox credentials
curl -X POST https://sandbox.adnx.ai/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{"email": "dev@yourplatform.example", "organization": "TalentFlow GmbH"}'
Response
{
"api_key": "adnx_test_k1_a3f8...",
"webhook_secret": "whsec_b7c2..."
}
2. Register a supply agent
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.


All API requests require a bearer token in the Authorization header.

Authorization: Bearer adnx_test_k1_a3f8...
Content-Type: application/json

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)
POST /api/v1/talent
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"
}
}'
Response -- 201 Created
{
"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.


Once a profile is submitted:

  1. Validation — The exchange validates the payload against OTP v0.2 JSON Schema (Draft 2020-12). Invalid profiles return a 422 with field-level errors.
  2. 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.
  3. Negotiation — For each match, the exchange creates a negotiation (pending -> evaluating -> matched). Both agents are notified.
  4. Audit — Every evaluation is immutably logged to the compliance vault with a vault:// reference.

Register a webhook endpoint to receive match results in real time instead of polling.

Register webhook
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.

Example webhook payload -- negotiation.matched
{
"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.


When a match is found, your agent can accept, reject, or counter with updated terms.

Accept a match
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"}'
Counter with updated salary expectations
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"}}}'

supply_node.py
from adnx import ADNXClient
client = ADNXClient(
api_key="adnx_test_k1_a3f8...",
webhook_secret="whsec_b7c2...",
)
# Register supply agent
agent = client.register_agent(
name="TalentFlow Supply Agent",
type="supply",
callback_url="https://yourplatform.example/webhooks/adnx",
)
# Submit a talent profile
result = 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 negotiations
matches = 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")