API Documentation
v1The Inbora API connects to email inboxes over IMAP and uses a locally-loaded AI model (Qwen2.5-1.5B-Instruct) to extract structured data. One endpoint handles all extraction types.
Base URL (Cloud)
https://api.inbora.devSelf-hosted
https://your-instance.fly.devAuthentication
All API requests must include an API key in the Authorization header using Bearer authentication.
API Key Format
Standard: INBX<40 random chars>
Pro: INBP<40 random chars>
Enterprise:INBE<40 random chars>
http
Authorization: Bearer INBX1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7q8r9s0
POST
/v1/extract
The main extraction endpoint. Connects to the specified inbox, scans recent emails matching your filters, and extracts the requested data type using AI inference.
Request Body
| Parameter | Type | Description |
|---|---|---|
emailrequired | string | The email address to connect to. |
passwordrequired | string | App password or account password for IMAP access. |
extraction_typerequired | 'otp' | 'link' | 'ticket' | Type of data to extract from the inbox. |
sender_filter | string | Filter emails by sender address (substring match). |
subject_filter | string | Filter emails by subject line (substring match). |
max_emails | number | Maximum emails to scan (default: 10, max: 500 on Scale). |
bash
curl -X POST https://api.inbora.dev/v1/extract \
-H "Authorization: Bearer INBX..." \
-H "Content-Type: application/json" \
-d '{
"email": "user@gmail.com",
"password": "app-password",
"extraction_type": "otp",
"sender_filter": "noreply@service.com",
"subject_filter": "Your verification",
"max_emails": 10
}'Response
json
{
"success": true,
"extraction_type": "otp",
"provider": "gmail.com",
"results": [
{
"type": "otp",
"value": "847291",
"confidence": 0.95,
"email_subject": "Your verification code",
"email_from": "noreply@service.com",
"email_date": "Fri, 10 Jan 2025 12:00:00 +0000",
"source_snippet": "Your one-time code is 847291..."
}
],
"emails_scanned": 5,
"latency_ms": 1423,
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}GET
/v1/health
Health check endpoint. No authentication required.
bash
curl https://api.inbora.dev/v1/health
json
{ "status": "ok", "model": "Qwen2.5-1.5B-Instruct", "version": "1.0.0" }POST
/v1/keys
Create a new API key. Available on Pro and Enterprise plans. The key is returned only once — store it securely.
bash
curl -X POST https://api.inbora.dev/v1/keys \
-H "Authorization: Bearer INBP..." \
-H "Content-Type: application/json" \
-d '{ "name": "Production Key" }'json
{
"id": "key_abc123",
"name": "Production Key",
"key": "INBP1a2b3c4d5e6f7g8h9i...",
"created_at": "2025-01-10T12:00:00Z"
}GET
/v1/keys
List all API keys for your account.
bash
curl https://api.inbora.dev/v1/keys \ -H "Authorization: Bearer INBP..."
DELETE
/v1/keys/{key_id}
Revoke an API key immediately.
bash
curl -X DELETE https://api.inbora.dev/v1/keys/key_abc123 \ -H "Authorization: Bearer INBP..."
Error Codes
| Status | Code | Description |
|---|---|---|
401 | unauthorized | Invalid or missing API key |
402 | plan_limit_exceeded | Monthly request limit reached |
422 | imap_auth_failed | Could not authenticate with inbox |
422 | no_emails_found | No emails matched the filters |
422 | extraction_failed | AI model could not extract data |
429 | rate_limited | Too many requests (slow down) |
500 | internal_error | Server error — we've been notified |
SDKs & Examples
Official SDKs are in development. In the meantime, use any HTTP client.
Python
python
import requests
response = requests.post(
"https://api.inbora.dev/v1/extract",
headers={"Authorization": "Bearer INBX..."},
json={
"email": "user@gmail.com",
"password": "app-password",
"extraction_type": "otp",
"sender_filter": "noreply@service.com",
}
)
data = response.json()
print(data["results"][0]["value"]) # "847291"Node.js
typescript
const response = await fetch("https://api.inbora.dev/v1/extract", {
method: "POST",
headers: {
"Authorization": "Bearer INBX...",
"Content-Type": "application/json",
},
body: JSON.stringify({
email: "user@gmail.com",
password: "app-password",
extraction_type: "otp",
sender_filter: "noreply@service.com",
}),
});
const data = await response.json();
console.log(data.results[0].value); // "847291"