OceanirDocs

API Reference

Complete reference for all Oceanir REST API endpoints. All endpoints require authentication via API key.

Base URL

https://oceanir.ai/api/v1

Authentication

Include your API key in the x-api-key header:

x-api-key: orc_...

Pricing and usage

Low-volume developer API access is included with Pro. Subscribe to Pro and create one personal key from Settings › Developers. Organizational, client-facing, batch, and production integrations require an Enterprise agreement with organization-scoped credentials.

Successful calls consume dedicated API credits at the depth cost below. Regular app credits and public credit packs do not fund API calls. Failed analyses are not charged. When the API balance is too low, the API returns HTTP 402. Contracted Enterprise overage is available only by written agreement.

Oceanir Pro includes 25 API-only credits each month. Active Pro members can buy up to two 25-credit API boosters for $10 each, adding up to 75 new API credits in a calendar month. This developer allowance is for individual development, testing, and low-volume internal use; organizational and client-facing production integrations require Enterprise.

Developer API allowance

25 creditsIncluded with Pro each month
25 credits · $10API-only booster
Two boostersMaximum purchased each month

Credit costs

Personal API calls use only dedicated Pro API credits. They never consume the shared web/app balance. Organization-scoped Enterprise calls use the contracted organization pool. The request defaults to D1 when depth is omitted.

Geolocation analysisD1, Surface1Region-level coordinates
Geolocation analysisD2, Standard2Block-level radius with visual evidence chain
Geolocation analysisD3, Forensic10Street-level lock with full reasoning + contradiction flags
Property verificationSoonConfirm a photo shows the property it claims to
Bulk analysisSoonProcess an image set in one submission

Example: the 75 credits a Pro developer can add in one month cover 7 D3 analyses with 5 credits remaining, 37 D2 analyses with 1 remaining, or 75 D1 analyses.

When Enterprise is required

The self-serve developer API is intentionally capped. Move to Enterprise when the integration represents an organization or becomes part of a production or client-delivery workflow.

More than 75 new API credits per month
More than one user or API key
Batch, webhook, or shared case workflows
Paid client deliverables, resale, DPA, or SLA requirements

Enterprise provides pooled organization credits, commercial-use rights, contracted limits, onboarding, and operational controls. Contact sales to scope an evaluation or production agreement.

Endpoints

POST/api/v1/geolocate
GET/api/v1/analyses
GET/api/v1/credits
GET/api/v1/usage
POST/api/v1/cases

POST /api/v1/geolocate

Submit one image, get ranked coordinates with confidence and visual reasoning. Authenticate with your key in Authorization: Bearer <key> or x-api-key: <key> — both work. For retry-safe execution and billing, reuse the same Idempotency-Key for every retry of one analysis. A completed retry replays the original response without another model call or credit debit; using that key with a different payload returns HTTP 409.

Request body (JSON)

image_b64stringone ofRaw base64-encoded JPEG/PNG without a data: URL prefix. Max 20MB.
image_urlstringone ofPublic URL to fetch the image from instead.
modelstringoptionalCurrently orca-1.5. Omit it or send exactly this value.
depthintegeroptional1 = Surface (region, 1 credit), 2 = Standard (block, 2), 3 = Forensic (street, 10). Default 1.
effortstringoptionalinstant | low | medium | high. How long the model reasons INSIDE the chosen depth. It can only LOWER the effort that depth normally runs (d1 low, d2 medium, d3 high); asking for more returns 422. Useful for staying inside a deadline: depth 3 runs for 70s at the median, so effort: "low" trades reasoning for the chance of an answer inside your timeout. It does not change which verification passes run, what the response contains, or the credit cost. Depth decides all three. Echoed back as effort.
batch_idstringoptionalNamed batch from the Platform console. It must be bound to the API key making this request.
scopeobjectoptionalPin the search to one city: { name, lat, lng, radius_km }. radius_km defaults to 60 and accepts 1 to 500. Omit scope entirely for a worldwide search, which is the default. The scope narrows where the model looks; it is never treated as evidence and never raises confidence. If the image carries hard contradicting evidence, wrong script on signage, a foreign plate format, the wrong driving side, or impossible terrain, the model overrides the scope, returns the honest estimate and reports scope_consistent: false. Invalid values return 422.

Example request

curl -X POST https://oceanir.ai/api/v1/geolocate \
  -H "Authorization: Bearer orc_YOUR_KEY" \
  -H "Idempotency-Key: your-unique-request-id" \
  -H "Content-Type: application/json" \
  -d '{
    "image_url": "https://example.com/street.jpg",
    "batch_id": "batch_YOUR_BATCH_ID",
    "depth": 2,
    "scope": { "name": "Lyon", "lat": 45.764, "lng": 4.836, "radius_km": 60 }
  }'

200 response

{
  "success": true,
  "analysis_id": "an_8X2k...",
  "location": {
    "latitude": 45.7700,
    "longitude": 4.8459,
    "country": "France",
    "city": "Lyon",
    "neighborhood": "6th arrondissement",
    "address": "Rue de Créqui, 69006 Lyon"
  },
  "confidence": 0.88,
  "reasoning": "French street signage, Haussmann facades, plane trees...",
  "thinking": "<step-by-step cues — depth >= 2 only>",
  "visual_clues": [
    { "label": "Street sign", "detail": "" },
    { "label": "Haussmann facade", "detail": "" }
  ],
  "model": "orca-1.5",
  "batch_id": "batch_YOUR_BATCH_ID",
  "depth": 2,
  "timing_ms": 9120
}

confidence is 0–1. thinking and visual_clues are returned only at depth ≥ 2. Each clue is { label, detail }. detail is currently always empty, and clues carry no image coordinates this example previously showed x and y fields the API has never returned.

The forensic object (depth 3 only)

At depth 3 the response carries an additional forensic object. This is what separates a forensic call from a standard one: instead of a single coordinate, you get the evidence the conclusion rests on, the evidence that argues against it, and the alternative locations that were considered and rejected. It is designed to be shown to a reviewer, not just consumed by a program.

precision_tierstringHow tightly the location is resolved: exact, site_level, neighborhood_level, city_level or region_level.
verification_statusstringWhether the conclusion was corroborated, partially corroborated, or left unverified.
supportsstring[]Specific visual evidence that argues FOR the returned location. Signage, architecture, road geometry, vegetation.
contradictionsstring[]Evidence that argues AGAINST it. A non-empty array is not a failure — it is the reason a reviewer should look closer before acting.
candidatesobject[]Alternative locations considered, each with lat, lng, label, confidence (0–100), supports and contradictions.
"forensic": {
  "precision_tier": "block",
  "verification_status": "partially_verified",
  "supports": [
    "Street sign reads 'Rue de Créqui'",
    "Haussmann-era facade with 6th-arrondissement cornice detail"
  ],
  "contradictions": [
    "Bollard style is more common in Lyon 3e than 6e"
  ],
  "candidates": [
    {
      "label": "Rue Vendôme, Lyon 6e",
      "lat": 45.7688,
      "lng": 4.8441,
      "confidence": 62,
      "supports": ["Matching tree spacing"],
      "contradictions": ["Street sign does not match"]
    }
  ]
}

Confidence is reported as the model assesses it and is not inflated when evidence is thin. A low score with populated contradictions is the system telling you it is not certain, which is the signal you want in a claim, a dispute, or a moderation decision.

Errors

401Missing or invalid API key.
402Insufficient credits for the requested depth.
409The Idempotency-Key is still processing or was already used with a different request payload.
422No image_b64 or image_url provided, or image_url could not be fetched.
422Returns code: "invalid_effort" for an unknown effort value, or code: "effort_exceeds_depth" when the requested effort is above what that depth runs. The latter carries max_effort.
404The batch_id does not exist or is bound to a different API key.
422Returns code: "content_blocked" when an image fails content-safety screening. Screening runs before credits are reserved, so a blocked image is never charged.
429Rate limit exceeded — retry after retry_after seconds.
422Returns code: "invalid_image_b64" when image_b64 is not decodable base64, or carries a data: URL prefix. Send raw base64.
422Returns code: "invalid_scope" when the optional scope field cannot be parsed as a city scope. Omit scope entirely for a worldwide analysis.
402Returns code: "prepaid_credits_exhausted" when an enterprise prepaid allocation is spent. Contact Oceanir rather than retrying.
409Returns code: "idempotency_in_progress" when the same Idempotency-Key is still being processed. Wait and retry the same key.
502Analysis failed upstream, code: "analysis_failed". Retry, or lower the depth. Not charged.
503Inference backend unavailable. Transient — retry with backoff. Not charged.
504Analysis timed out before completion. Returns code: "analysis_timeout" and retryable: true. Credits are refunded automatically — safe to retry, or use a lower depth.