OwnClimb Detection API

Asynchronous climbing-hold detection. Submit a wall image, then poll for the run's result. The OpenAPI document is the machine-readable contract for the same reference.

Base URL: https://ownclimb.com/api/v1

Authentication

Send your oc_ API key as Authorization: Bearer <key>, or as the X-API-Key header.

Quickstart

Submit an image:

curl -X POST https://ownclimb.com/api/v1/runs \
  -H "Authorization: Bearer oc_your_key" \
  -F "image=@wall.jpg" \
  -F 'metadata={"gym":"north"}'
# → 202 { "id": "…", "status": "queued", … }

Poll for the result:

curl https://ownclimb.com/api/v1/runs/RUN_ID \
  -H "Authorization: Bearer oc_your_key"
# → 200 { "status": "done", "result": { "holds": [ … ] } }

Endpoints

POST /api/v1/runs

Submit an image for hold detection.

Multipart form with an image file and optional JSON fields. Returns 202 immediately; the run is processed asynchronously.

FieldTypeRequiredDescription
imagefileyesWall photo (JPEG/PNG/WebP/HEIC, max 40 MB).
configstringnoDetection config id. Defaults to the standard config.
metadataJSON stringnoOptional object echoed back in run history.
StatusMeaning
202Run accepted and queued.
400invalid_request or invalid_image.
401unauthorized.
402quota_exceeded or account_locked.
413image_too_large.
429rate_limited; wait out the retry-after header.

GET /api/v1/runs/{id}

Get a run.

Path parameterRequiredDescription
idyesThe run's uuid.
StatusMeaning
200Current run state; result.holds is present once status is done.
401unauthorized.
404not_found.

GET /api/v1/runs/{id}/progress

Stream a run's progressive stages.

Server-sent events (text/event-stream) that deliver the run's stages as they finish: status with the current state, progress with the holds each stage has found so far, then done with the final run or failed with the error. The stream ends at the terminal event, or after two minutes if the worker never finishes.

Path parameterRequiredDescription
idyesThe run's uuid.
StatusMeaning
200The SSE stream.
401unauthorized.
404not_found.

Error codes

Errors come back as { "error": { "code", "message" } }, with an optional details object on validation failures.

CodeStatusMeaning
invalid_request400The request or its fields are not valid.
invalid_image400The upload does not decode as an image.
image_too_large413The image exceeds the size limit.
unauthorized401Missing or invalid API key.
not_found404No such run, or it belongs to another account.
quota_exceeded402The monthly inference quota is used up.
account_locked402The subscription is inactive.
rate_limited429Too many requests; retry after the delay.
inference_failed500The detection run failed.
storage_unavailable503Image storage was unreachable.