Getting started

Authentication

Every Pedra API request authenticates with an API key passed in the JSON body.

Getting an API key

  1. Sign up at app.pedra.ai.
  2. Open Settings → API.
  3. Copy your key. It's long-lived and tied to your account.

For higher quotas, dedicated capacity, or enterprise pricing, email felix@pedra.ai.

Building an agent? It can get a key for the person it works for by email, with their approval — see Accounts for AI agents.

Using the key

Pass the key as apiKey in the JSON request body for every endpoint. There is no header-based auth, OAuth flow, or token refresh — keys are long-lived and tied to your account.

curl -X POST https://app.pedra.ai/api/enhance \
  -H "Content-Type: application/json" \
  -d '{
    "apiKey": "YOUR_API_KEY",
    "imageUrl": "https://example.com/photo.jpg"
  }'

Keeping your key safe

  • Never ship keys in client-side code. Calls must originate from your backend. A key embedded in a browser bundle or mobile app is effectively public.
  • Store keys as environment variables. Not in source control.
  • Rotate immediately if leaked. Email us — we'll revoke the old key and issue a new one.

Errors

Missing or invalid keys return HTTP 404 with {"error": "User not found"} — Pedra looks the key up as a user record, so an unknown key reads as a missing user. See Errors & limits for the full list of failure modes.

Accounts for AI agents

An AI agent can get an API key for the person it works for — creating their Pedra account if they don't have one — without either of them opening Settings. It's for agents with no browser in the loop: Claude Code, a script, the local MCP server, anything that only speaks HTTP. The person approves from their inbox; the agent never sees a password.

ChatGPT and Claude connectors don't need this. Connecting Pedra there signs the person in with OAuth, and new users can create their account in that same sign-in tab. See MCP server.

  1. The agent calls agent_signup with the person's email. Pedra emails them a confirmation link, valid for 30 minutes.
  2. The agent tells the person to check their email. They open the link: a new account says what they do, picks a language, chooses a password (8+ characters) and clicks Create account and allow; an existing account clicks Allow. They can also decline. Nothing is created until they click.
  3. Meanwhile the agent polls agent_signup_status every 5 seconds. Once approved, the response has the apiKey — available for 15 minutes after approval, so store it. The key itself doesn't expire.

To keep this from being used to farm free accounts or spam inboxes: no account exists without a click in the inbox, disposable email domains are refused, requests are rate-limited per address and per IP, and the response is the same whether or not the address already has an account.

The whole flow, with a polling loop:

# 1. Ask for access. Pedra emails the person a confirmation link.
curl -X POST https://app.pedra.ai/api/agent_signup \
  -H "Content-Type: application/json" \
  -d '{ "email": "maria@example.com", "agentName": "Claude Code" }'

# 2. Poll every 5 seconds until status is no longer "pending".
curl -X POST https://app.pedra.ai/api/agent_signup_status \
  -H "Content-Type: application/json" \
  -d '{ "requestId": "REQUEST_ID" }'

Request access

POST/api/agent_signup

No apiKey needed. Starts a request and emails the person the confirmation link. Returns a requestId to poll with.

emailstringrequired
The email address of the person the agent works for. A new account is created for it if none exists, once they confirm.
agentNamestring
Who is asking, shown in the email and on the confirmation page, e.g. "Claude Code". Up to 60 characters.

400 — not a valid email address, or code: "disposable_email" (use a permanent address). 429 rate_limited — 3 requests an hour per address, 10 a day per IP, plus a global daily cap; the link already sent still works. 503 unavailable — signup by email is down; the person can sign up at app.pedra.ai and copy a key from Settings → API.

Response

JSON
{
  "requestId": "hT4kP9wZ2mQ7xR1vB8nC3sD6fG0jL5yE...",
  "status": "pending",
  "expiresAt": "2026-09-30T10:30:00.000Z",
  "pollAfterSeconds": 5,
  "message": "We emailed a link to maria@example.com. Ask the person to open it and confirm (new accounts set a password there). Then poll agent_signup_status with this requestId to get the API key."
}

Check an agent signup

POST/api/agent_signup_status

No apiKey needed. Returns one of four statuses:

  • pending — the person hasn't clicked yet. Poll again in 5 seconds.
  • approved — with apiKey, email, newAccount, plan, creditsRemaining and appUrl. A new account starts with Pedra's free trial credits. If creditsRemaining is 0 there's also a note saying the person can get credits with a plan; pass it on. Free calls such as listing properties always work.
  • denied — the person declined. Stop polling.
  • expired — nobody clicked within 30 minutes, or the key wasn't collected within 15 minutes of approval. Start again with agent_signup. An unknown requestId returns 404.
requestIdstringrequired
The requestId returned by agent_signup.

Response

JSON
{
  "status": "pending",
  "pollAfterSeconds": 5
}