Getting Started
Learn how to interact with the oJo API.
What you get
- Synchronous by default. A render request returns the finished file in the same HTTP response —
{ id, imageUrl, createdAt }for an image,{ id, pdfUrl, pages, createdAt }for a PDF. No job id to poll, no webhook to receive, no second request. - Bulk in one call.
POST /v1/image/bulkrenders many images from many templates in a single request, at 1 credit per image. - 60 renders per minute. Image and PDF endpoints share 60 requests per 60 seconds; template and transform endpoints allow 30. See Rate Limits.
- Your files do not expire. Rendered images and PDFs stay at their URL for as long as your account is active. Nothing removes them on a timer — a file is deleted when you delete it.
- 30 credits to start, no card. Signing up issues 30 trial credits, valid for 30 days. No payment method is required to get them.
- Renders in about a second. Measured against production on 2026-08-11: a saved template renders in ~0.6 s at the median, self-contained HTML in ~0.85 s, and HTML that pulls external fonts or images in ~1.2 s — p95 under 1.8 s in all three cases. A measurement, not an SLA.
Base URL
https://api.ojo.soAuthentication
To authenticate with the API, you need to provide an API key in the Authorization header.
Authorization: Bearer <Your API Key>You can obtain your API key from the API settings .
Response Codes
The API uses standard HTTP response codes to indicate the success or failure of an API request.
200 OK- Everything worked as expected.400 Bad Request- The request was unacceptable, often due to missing a required parameter.401 Unauthorized- No valid API key provided.402 Payment Required- The request requires payment.403 Forbidden- The API key doesn’t have permissions to perform the request.404 Not Found- The requested resource doesn’t exist.408 Request Timeout- The request took too long to process.422 Unprocessable Entity- The request was well-formed but was unable to be followed due to validation errors.429 Too Many Requests- Too many requests hit the API too quickly.500 Internal Server Error- We had a problem with our server. Try again later.503 Service Unavailable- We’re temporarily offline for maintenance. Please try again later.
Rate Limits
The oJo API implements endpoint-specific rate limiting to ensure fair usage and system stability. Rate limits are tracked per user and enforced across all API requests.
Current Rate Limits
| Endpoint Type | Rate Limit | Time Window | Block Duration |
|---|---|---|---|
| Image and PDF Operations | 60 requests | 60 seconds | 120 seconds |
| Template Operations | 30 requests | 60 seconds | 120 seconds |
| Image Transform Operations | 30 requests | 60 seconds | 120 seconds |
When you make an API request, the response will include headers that provide information about your current rate limit status:
X-RateLimit-Policy: <endpoint-type>:<requests>/<seconds>s
X-RateLimit-Limit: <maximum requests allowed>
X-RateLimit-Remaining: <requests remaining>
X-RateLimit-Reset: <ISO timestamp when the limit resets>Rate Limit Exceeded
If you exceed the rate limit, you’ll receive a 429 Too Many Requests response with the following headers:
HTTP/1.1 429 Too Many Requests
X-RateLimit-Policy: <endpoint-type>:<requests>/<seconds>s
X-RateLimit-Limit: <maximum requests allowed>
X-RateLimit-Remaining: 0
X-RateLimit-Reset: <ISO timestamp when the limit resets>
Retry-After: <seconds until next request is allowed>Best Practices
To work effectively with these rate limits:
- Monitor the
X-RateLimit-Remainingheader to track your remaining requests - Use the
X-RateLimit-Resettimestamp to schedule requests appropriately - When receiving a 429 response, wait for the duration specified in the
Retry-Afterheader before retrying - Implement exponential backoff in your retry logic
- Consider implementing request queuing for high-volume operations
Example Response Headers
For image and PDF operations:
X-RateLimit-Policy: image:60/60s
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 2024-11-06T15:30:45.066Z
Retry-After: 87For template operations:
X-RateLimit-Policy: template:30/60s
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 29
X-RateLimit-Reset: 2024-11-06T15:30:45.066ZResource Limits
Your HTML runs in a browser, JavaScript included. Browser storage (localStorage,
sessionStorage, IndexedDB, the Cache API) and Web Workers are off, so a library that needs them
will not work.
Images, fonts, stylesheets and scripts load from public https:// addresses. Images can also be
data: URLs. Plain http:// and private or internal addresses are refused.
| Limit | Value |
|---|---|
| Each document, script, stylesheet or font | 1 MB |
| Each image | 5 MB |
| All resources of one page together | 10 MB |
| Time to fetch one resource | 5 s |
| Redirects per resource | 5 |
| Page load | 5 s |
Wait for render-complete (charts) | 5 s |
A resource that breaks a limit or is refused fails the render. When render-complete does not
appear within 5 s, the page is captured as it is.
Caveats
oJo API is currently in public beta and subject to change. We will do our best to notify you of any changes.