Unlock entities (unified)
Unified unlock endpoint for districts, schools, and contacts. Routes through the unlock orchestrator, which decides between three paths: - **Fast path** (`outcome: "unlocked"`, HTTP 200): the entity already has extracted intelligence on file. Credits are deducted immediately and the intelligence is revealed for this org. - **Slow path** (`outcome: "unlock_pending"`, HTTP 202): the entity has no extracted intelligence yet. Credits are held against your balance, the extraction pipeline is triggered (~3-5 minutes), and the hold is committed to a real deduction on success or refunded on failure. Poll `GET /unlock-status/{entityType}/{entityId}` until the pipeline completes. - **Idempotent** (`outcome: "idempotent"`, HTTP 200): the org has already unlocked this entity. Returns immediately with 0 credits charged. **Contact unlocks require the parent district or school to be unlocked first.** If the parent is locked, the response is 403 PARENT_ENTITY_LOCKED. Optional `re_extract: true` (districts/schools only) re-triggers extraction on an already-unlocked entity. Charges credits again. Not valid for contacts. **Credit costs:** District (6School (6), Contact (2).
Unified unlock endpoint for districts, schools, and contacts. Routes through the unlock orchestrator, which decides between three paths:
- Fast path (
outcome: "unlocked", HTTP 200): the entity already has extracted intelligence on file. Credits are deducted immediately and the intelligence is revealed for this org. - Slow path (
outcome: "unlock_pending", HTTP 202): the entity has no extracted intelligence yet. Credits are held against your balance, the extraction pipeline is triggered (~3-5 minutes), and the hold is committed to a real deduction on success or refunded on failure. PollGET /unlock-status/{entityType}/{entityId}until the pipeline completes. - Idempotent (
outcome: "idempotent", HTTP 200): the org has already unlocked this entity. Returns immediately with 0 credits charged.
Contact unlocks require the parent district or school to be unlocked first. If the parent is locked, the response is 403 PARENT_ENTITY_LOCKED.
Optional re_extract: true (districts/schools only) re-triggers extraction on an already-unlocked entity. Charges credits again. Not valid for contacts.
Credit costs: District (6School (6), Contact (2).
API key (sk_live_... prefix). Generate keys in the UI under Settings > API Keys, then send it as Authorization: Bearer sk_live_...
In: header
Request Body
application/json
Type of entity to unlock (required for single unlock)
"district" | "school" | "contact"Single entity UUID (required for single unlock)
Array of entities (for batch unlock)
"dashboard" | "mcp" | "api"Re-trigger extraction on an already-unlocked district/school.
Response Body
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://loading/api/v1/unlock" \ -H "Content-Type: application/json" \ -d '{}'{
"outcome": "idempotent",
"unlocked": true,
"already_unlocked": true,
"credits_charged": 0,
"credits_held": 0,
"credits_remaining": 0,
"hold_id": "string",
"operation_key": "string",
"job_id": "string",
"message": "string"
}{
"outcome": "unlock_pending",
"unlocked": false,
"already_unlocked": true,
"credits_charged": 0,
"credits_held": 0,
"credits_remaining": 0,
"hold_id": "string",
"operation_key": "string",
"job_id": "string",
"message": "string"
}{
"error": "string",
"message": "string",
"statusCode": -9007199254740991
}{
"error": "string",
"message": "string",
"balance": 0,
"required": 0
}{
"error": "PARENT_ENTITY_LOCKED",
"message": "string",
"parent_entity_type": "district",
"parent_entity_id": "550e8400-e29b-41d4-a716-446655440000",
"unlock_cost": 0
}Get school vendor stack GET
Get technology/vendor stack for a school. Requires unlock.
Poll extraction status for a pending unlock GET
After /unlock returns `outcome: "unlock_pending"`, poll this endpoint until status becomes `completed` or `failed`. Returns the pipeline phase, percent complete, and an error message if the pipeline failed. Contacts are not supported here (their enrichment is resolved automatically by the credit-hold cron). **Free (0 credits).**