Reference

Errors & limits

HTTP status codes, error response shapes, credit limits, and timeout behavior across all Pedra API endpoints.

Error response shape

Failed requests return a non-200 HTTP status with a JSON body containing an error field describing what went wrong.

JSON
{
  "error": "User not found"
}

Status codes

The Pedra API uses a deliberately small set of status codes. There's no 401 and no 413 — an unknown API key returns 404. Running out of credits returns 403 on the image, video and voice endpoints and 402 on the virtual tour endpoints. 429 is used only for the daily upload limits and agent signup — there are no per-second or per-minute rate limits.

Status
Meaning
200
Success. Image endpoints return output (array or single object — see each endpoint); the video endpoint returns videoId and a ready-to-stream videoUrl.
400
Bad request. Image endpoints return this when imageUrl doesn't return a valid image (non-200 response, or bytes that aren't a decodable image). Also returned by /api/create_video for a missing images array, a missing imageUrl in an image, an invalid effect value, or effect: "transition" without secondImageUrl.
402
Insufficient credits on the virtual tour endpoints (create_virtual_tour, add_virtual_tour_scenes). The body has code: "insufficient_credits", creditsRequired, creditsAvailable and upgradeUrl. Nothing is created or charged.
403
Insufficient credits on the image, video and voice endpoints. The error message explains how many credits the call required vs. how many remain. Top up at app.pedra.ai or email felix@pedra.ai.
404
{"error": "User not found"} — the API key didn't match any account. This is the response for missing, invalid, or revoked keys.
405
Method not allowed. All endpoints accept only POST.
429
A daily limit was reached. code tells you which: upload_limit (daily upload limit), upload_link_limit (upload links per day) or rate_limited (agent signup). See Daily upload limit.
500
Server error. Most often surfaces the underlying processing exception in the error field.

Common errors

User not found (404)

The API key didn't match any Pedra account. Verify the key matches what we issued and that it's in the JSON body as apiKey — not as an Authorization header.

Insufficient credits (403 / 402)

Each plan comes with a monthly credit allowance — see pedra.ai/pricing. Image endpoints cost 1 credit; each non-static video frame costs 5. When you run out, you'll get a 403 with the exact credit math (a 402 with creditsRequired and creditsAvailable on the virtual tour endpoints). Top up or change plan at app.pedra.ai → Settings → Subscription and credits.

JSON
{
  "error": "Insufficient credits. You need 5 credits but only have 2 remaining. Please purchase more credits at app.pedra.ai or contact felix@pedra.ai for support."
}

Invalid effect 'X' at index N (400)

The video endpoint validates effect against the set [zoom-in, zoom-out, transition, static]. The error message names the offending image index.

imageUrl did not return a valid image (400)

The imageUrl didn't point to a usable image. Either the URL responded with a non-200 status (commonly a 404 HTML error page served at a .png URL), or the downloaded bytes weren't a decodable image. Open the URL in a private browser window to confirm it returns the actual image file — not a login, error, or placeholder page.

Image fetch failed (500)

Pedra couldn't download the imageUrl within 20 seconds. Causes: auth-walled URL, expired presigned URL, slow origin. For presigned S3/R2/Cloudinary URLs, send the image as a data:image base64 URI instead — Pedra will use the bytes directly.

Rate limits

There are no per-second or per-minute rate limits on the Pedra API. Throughput is bounded by your remaining credits and the underlying processing capacity. The only limits are daily ones: on photos brought in from outside the app (below), on upload links, and on agent signup. If you're running high-volume batches and need a guaranteed throughput floor, email felix@pedra.ai.

Daily upload limit

Every image stored from outside the app counts toward a daily allowance per account: 30 a day on the free plan, 500 a day on paid plans, reset at midnight UTC. What counts:

  • add_images_to_property (URLs and data: URIs)
  • 360° photos passed by URL to create_virtual_tour and add_virtual_tour_scenes
  • Files uploaded through an upload link, and photos attached in ChatGPT that get added to a property

Photos you edit by imageUrl and photos uploaded in the Pedra app don't count. Over the limit, the call returns 429 with code: "upload_limit" and is refused as a whole — nothing is stored. Items that fail on their own (a URL that doesn't load, a photo that isn't 360°) don't count. Need more room on a paid plan? Email felix@pedra.ai.

JSON
{
  "error": "Daily upload limit reached (30 images per day on this plan). It resets at midnight UTC. Paid plans have a higher limit: https://www.pedra.ai/pricing",
  "code": "upload_limit"
}

Two related daily limits: upload_link_limit — 5 upload links a day on the free plan, 50 on paid plans (each link works for 24 hours, so reuse it); and rate_limited — agent signup requests per email address and per IP.

Timeouts

  • Image fetch: Pedra gives up after 20 seconds trying to download imageUrl.
  • Image endpoints (enhance, furnish, empty_room, renovation, etc.): typical response 10–30 seconds.
  • Video endpoint: synchronous — blocks while the video renders, which can take several minutes. Set your HTTP client timeout generously.

Retrying safely

All endpoints are idempotent within a request — retrying the same body produces a new generation, never a corrupted state. Failed requests (4xx/5xx) do not consume credits in most paths; the credit deduction happens inside the Meteor method once processing starts.

Need help?

Email felix@pedra.ai with the failing request body and response. We respond within one business day. See Pricing for credit and quota options.