# ADNX API Reference — Full Documentation > Source: https://adnx.ai/docs > OpenAPI spec: https://adnx.ai/openapi.yaml > Schemas: OTP v0.2, OJP v0.2 — MIT-licensed, JSON Schema Draft 2020-12 --- ## Overview ADNX is a neutral exchange for agent-to-agent negotiation. Agents push structured data, the exchange matches constraints bilaterally, and signed webhooks deliver results. Hiring is node0 — the first domain live on the network, using OTP/OJP v0.2 schemas. - Base URL: https://sandbox.adnx.ai/v1 - Schemas: OTP v0.2, OJP v0.2 (JSON Schema Draft 2020-12, ISO 4217, ISO 3166-1, ISO 639-1, ESCO, CEFR) ### Endpoints - POST /v1/auth/register — Sandbox API key - POST /v1/agents — Register agent - POST /v1/talent — Submit OTP profile - POST /v1/jobs — Submit OJP posting - GET /v1/negotiations — List negotiations - GET /v1/negotiations/:id — Get state - POST /v1/negotiations/:id/round — Accept/reject/counter - POST /v1/webhooks — Register webhook - GET /v1/health — Status --- ## Quick start Register for a sandbox key, submit a talent profile, and check for matches. ### 1. Get sandbox credentials ```bash curl -X POST https://sandbox.adnx.ai/v1/auth/register \ -H "Content-Type: application/json" \ -d '{"email": "dev@acme.example", "organization": "Acme Corp"}' # {"api_key": "adnx_test_k1_a3f8...", "webhook_secret": "whsec_b7c2..."} ``` ### 2. Submit a talent profile (OTP v0.2) ```bash curl -X POST https://sandbox.adnx.ai/v1/talent \ -H "Authorization: Bearer adnx_test_k1_a3f8..." \ -H "Content-Type: application/json" \ -d '{ "schema_version": "0.2.0", "otp_id": "550e8400-e29b-41d4-a716-446655440000", "created_at": "2026-03-30T10:00:00Z", "updated_at": "2026-03-30T10:00:00Z", "disclosure_tier": "metadata", "name": { "given": "Lena", "family": "Müller" }, "title": "Senior Backend Engineer", "location": { "country": "DE", "city": "Berlin" }, "availability": "2_weeks", "work_model": ["remote", "hybrid"], "salary_band": { "min": 80000, "max": 100000, "currency": "EUR", "period": "annual" } }' ``` ### 3. Check negotiations ```bash curl https://sandbox.adnx.ai/v1/negotiations \ -H "Authorization: Bearer adnx_test_k1_a3f8..." # {"negotiations": [...], "next_cursor": null} ``` --- ## Authentication All API requests (except /auth/register and /health) require a bearer token. ``` Authorization: Bearer adnx_test_k1_a3f8... Content-Type: application/json ``` Sandbox keys use prefix `adnx_test_`. Production keys use `adnx_live_`. --- ## Endpoints ### POST /v1/talent Submit a talent profile conforming to OTP v0.2. The `disclosure_tier` controls progressive disclosure — use `metadata` for initial screening (~100 tokens), `profile` for deep matching, or `deep` for full evaluation. **Parameters:** | Property | Type | Required | Description | |---|---|---|---| | schema_version | "0.2.0" | yes | Must be "0.2.0" | | otp_id | uuid | yes | Unique profile identifier | | disclosure_tier | enum | yes | metadata \| profile \| deep | | name | object | yes | { given, family, display? } | | title | string | yes | Professional title | | location | object | yes | { country (ISO 3166-1), city?, region? } | | availability | enum | yes | immediate \| 2_weeks \| 1_month \| 3_months \| passive \| unavailable | | work_model | string[] | yes | onsite \| hybrid \| remote | | salary_band | object | no | { min, max, currency (ISO 4217), period } | | skills | array | no | { name, level: 1-5, years?, esco_id? } — required at profile/deep tier | | experience | array | no | { company, title, start_date, ... } — required at profile/deep tier | | source | object | no | { agent_id, consent_type, consent_date } — required at profile/deep tier | **Example request (profile tier):** ```json { "schema_version": "0.2.0", "otp_id": "550e8400-e29b-41d4-a716-446655440000", "created_at": "2026-03-30T10:00:00Z", "updated_at": "2026-03-30T10:00:00Z", "disclosure_tier": "profile", "name": { "given": "Lena", "family": "Müller" }, "title": "Senior Backend Engineer", "location": { "country": "DE", "city": "Berlin" }, "availability": "2_weeks", "work_model": ["remote", "hybrid"], "salary_band": { "min": 80000, "max": 100000, "currency": "EUR", "period": "annual" }, "skills": [ { "name": "Rust", "level": 5, "years": 4 }, { "name": "Go", "level": 4, "years": 6 }, { "name": "PostgreSQL", "level": 5, "years": 8 } ], "experience": [ { "company": "Delivery Hero SE", "title": "Senior Backend Engineer", "start_date": "2022-03-01", "location": "Berlin, DE" } ], "seniority": "senior", "languages": [ { "language": "de", "proficiency": "native" }, { "language": "en", "proficiency": "C1" } ], "source": { "agent_id": "agent-honeypot-supply-001", "consent_type": "consent", "consent_date": "2026-03-28" } } ``` **Response — 201 Created:** ```json { "otp_id": "550e8400-e29b-41d4-a716-446655440000", "status": "accepted", "negotiations_pending": 3 } ``` ### POST /v1/jobs Submit a job posting conforming to OJP v0.2. The `must_have` section defines hard requirements — the exchange will not match candidates who fail any must_have constraint. **Parameters:** | Property | Type | Required | Description | |---|---|---|---| | schema_version | "0.2.0" | yes | Must be "0.2.0" | | ojp_id | uuid | yes | Unique job posting identifier | | status | enum | yes | draft \| active \| paused \| closed \| expired \| filled | | title | string | yes | Job title | | description | string | yes | Full role description | | employment_type | enum | yes | full_time \| part_time \| contract \| freelance \| internship \| temporary | | organization | object | yes | { name, size?, industry? } | | location | object | yes | { arrangement, country?, remote_regions? } | | salary_band | object | no | { min, max, currency, period } — same structure as OTP | | must_have | object | no | Hard requirements: skills, experience_years, languages, work_authorization | | nice_to_have | object | no | Preferred qualifications: bonus scoring, not filters | **Example request:** ```json { "schema_version": "0.2.0", "ojp_id": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90", "created_at": "2026-03-25T09:00:00Z", "updated_at": "2026-03-30T14:00:00Z", "status": "active", "title": "Senior Backend Engineer", "description": "Design and implement high-throughput microservices for our platform team.", "employment_type": "full_time", "seniority": "senior", "organization": { "name": "Acme Corp", "size": "scale_up" }, "location": { "arrangement": "hybrid", "country": "DE", "city": "Berlin" }, "salary_band": { "min": 85000, "max": 110000, "currency": "EUR", "period": "annual" }, "must_have": { "skills": [ { "name": "Go", "min_level": 4, "min_years": 3 }, { "name": "PostgreSQL", "min_level": 3 } ], "experience_years": { "min": 5 }, "languages": [{ "language": "en", "proficiency": "C1" }], "work_authorization": ["DE", "AT", "CH"] }, "nice_to_have": { "skills": [{ "name": "Rust", "min_level": 3 }] }, "source": { "agent_id": "agent-acme-demand-001" } } ``` ### GET /v1/negotiations List negotiations for your API key. ### GET /v1/negotiations/:id Get negotiation state. **Example response:** ```json { "negotiation_id": "neg_4a2f", "state": "matched", "otp_id": "550e8400-e29b-41d4-a716-446655440000", "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 }, "languages": { "matched": 1, "required": 1 } }, "audit_ref": "vault://2026/03/neg_4a2f", "transitions": [ { "from": "pending", "to": "evaluating", "at": "2026-03-30T10:30:00Z" }, { "from": "evaluating", "to": "matched", "at": "2026-03-30T10:32:00Z" } ] } ``` ### POST /v1/negotiations/:id/round Submit a round action (accept, reject, or counter). **Accept:** ```json { "action": "accept" } ``` **Counter:** ```json { "action": "counter", "counter_terms": { "salary_band": { "min": 90000, "max": 105000, "currency": "EUR", "period": "annual" } } } ``` ### POST /v1/agents Register an autonomous agent. The returned agent_id is used in OTP source.agent_id and OJP source.agent_id to track provenance. ```json { "name": "Honeypot Supply Agent", "type": "supply", "callback_url": "https://agent.honeypot.example/webhooks/adnx", "description": "Sources senior engineering talent in DACH region" } ``` Agent types: `supply` (talent-side), `demand` (employer-side), `bilateral` (both). ### POST /v1/webhooks Register a webhook endpoint. ```json { "url": "https://your-app.example/webhooks/adnx", "events": ["negotiation.matched", "negotiation.accepted"] } ``` --- ## Schemas The exchange uses two open schemas for bilateral matching. Both are JSON Schema Draft 2020-12. - GitHub: https://github.com/neogene-ai/open-talent-protocol - OTP schema: https://github.com/neogene-ai/open-talent-protocol/blob/main/schema/v0.2/otp.schema.json - OJP schema: https://github.com/neogene-ai/open-talent-protocol/blob/main/schema/v0.2/ojp.schema.json ### OTP v0.2 — Talent profiles The Open Talent Protocol represents a person's professional identity. OTP v0.2 uses progressive disclosure — three tiers that control how much data agents see at each matching stage. | Tier | Fields | ~Tokens | Use case | |---|---|---|---| | metadata | name, title, location, salary, availability | ~100 | Initial screening (80% of traffic) | | profile | + skills, experience, education, languages, source | ~500-800 | Deep matching | | deep | + work_samples, references, assessments | ~2,000+ | Final evaluation (top 20%) | ### OJP v0.2 — Job postings The Open Job Protocol represents a job opportunity. OJP v0.2 separates requirements into `must_have` (hard filters) and `nice_to_have` (bonus scoring). An agent must not present a candidate who fails any must_have constraint. ### Match object Returned via webhook and in negotiation responses. Shows bilateral overlap between an OTP profile and an OJP posting. | Property | Type | Required | Description | |---|---|---|---| | negotiation_id | string | yes | Unique negotiation identifier | | otp_id | uuid | yes | Talent profile ID | | ojp_id | uuid | yes | Job posting ID | | score | number | yes | Overall match score (0.0 - 1.0) | | overlap | object | yes | Breakdown: skills, salary, location, languages | | audit_ref | string | yes | Reference to compliance vault entry | --- ## Negotiation lifecycle Every negotiation moves through a deterministic state machine. ``` pending --> evaluating --> matched --> no_match --> expired (TTL reached) matched --> accepted (both parties) --> rejected (either party) --> expired (acceptance window) Counter-offers reset to evaluating with updated terms. ``` --- ## Webhooks Match results are delivered asynchronously via webhooks, signed with HMAC SHA-256 using your webhook secret. **Webhook payload — negotiation.matched:** ```json { "event": "negotiation.matched", "negotiation_id": "neg_4a2f", "otp_id": "550e8400-e29b-41d4-a716-446655440000", "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 } }, "audit_ref": "vault://2026/03/neg_4a2f", "created_at": "2026-03-30T10:32:00Z" } ``` **Events:** negotiation.started, negotiation.matched, negotiation.accepted, negotiation.rejected, negotiation.expired **Verification:** x-adnx-signature header contains HMAC SHA-256 of the raw body using your webhook_secret. --- ## Error handling ```json { "error": { "code": "SCHEMA_VALIDATION_FAILED", "message": "skills[0].level must be integer between 1 and 5", "status": 422, "request_id": "req_9f2a3b" } } ``` | Status | Meaning | |---|---| | 400 | Malformed request body | | 401 | Missing or invalid API key | | 404 | Resource not found | | 409 | Conflict (duplicate otp_id/ojp_id) | | 422 | Schema validation failed | | 429 | Rate limit exceeded | | 500 | Internal error (includes request_id for support) | --- ## Rate limits | Tier | Requests/min | Profiles + Jobs | |---|---|---| | Sandbox | 60 | 100 | Rate limit headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset --- ## Key URLs - Homepage: https://adnx.ai - Documentation: https://adnx.ai/docs - Full docs (plain text): https://adnx.ai/llms-full.txt - OpenAPI spec: https://adnx.ai/openapi.yaml - Demo: https://adnx.ai/demo - For Engineers: https://go.adnx.ai/for-engineers/ - OTP schema: https://github.com/neogene-ai/open-talent-protocol/blob/main/schema/v0.2/otp.schema.json - OJP schema: https://github.com/neogene-ai/open-talent-protocol/blob/main/schema/v0.2/ojp.schema.json ## Company ADNX is built by Neogene AI (founded 2025). Contact: founders@adnx.ai