Async API
Asynchronous API with intelligent retry for reliable processing
Async API
The Async API provides queue-based processing with intelligent retry logic. Submit your requests and let RequestRocket handle retries automatically with exponential backoff.
Overview
Once a proxy has been configured, you can make asynchronous API requests that offer:
- Intelligent Retry: Up to 10 retries over 15 minutes
- Exponential Backoff: Smart retry timing with jitter
- Request Tracking: Monitor request status via request ID
- Reliability: Perfect for unreliable networks or batch operations
Endpoint Format
https://{region_specific_baseURL}/async/{proxyId}/{your_target_path}URL Components
- region_specific_baseURL: The regional endpoint (e.g.,
us-east-1.requestrocket.com) - proxyId: Your proxy's unique identifier
- your_target_path: The path on your target API
Note the /async/ segment in the URL - this routes your request to the asynchronous processing queue.
Authentication
Authentication works the same as the Proxy API, using your configured proxy credential.
Supported authentication methods:
- API Key
- Bearer Token
- JWT
- Basic Auth
HTTP Methods
The Async API primarily supports:
- POST: Submit data for processing
- PUT: Update operations
- PATCH: Partial updates
- DELETE: Remove operations
GET requests are not recommended for the Async API as they don't benefit from queuing and retry logic.
Making Async Requests
Basic Request
const response = await fetch(
'https://us-east-1.requestrocket.com/async/abc123/webhooks',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer your-proxy-token'
},
body: JSON.stringify({
event: 'user.created',
data: {
id: 'user_123',
email: 'john@example.com'
}
})
}
);
const result = await response.json();
console.log('Request ID:', result.requestId);import requests
response = requests.post(
'https://us-east-1.requestrocket.com/async/abc123/webhooks',
headers={
'Content-Type': 'application/json',
'Authorization': 'Bearer your-proxy-token'
},
json={
'event': 'user.created',
'data': {
'id': 'user_123',
'email': 'john@example.com'
}
}
)
result = response.json()
print(f"Request ID: {result['requestId']}")package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
type AsyncRequest struct {
Event string `json:"event"`
Data map[string]interface{} `json:"data"`
}
type AsyncResponse struct {
Message string `json:"message"`
RequestID string `json:"requestId"`
Status string `json:"status"`
}
func main() {
requestBody, _ := json.Marshal(AsyncRequest{
Event: "user.created",
Data: map[string]interface{}{
"id": "user_123",
"email": "john@example.com",
},
})
req, _ := http.NewRequest("POST", "https://us-east-1.requestrocket.com/async/abc123/webhooks",
bytes.NewBuffer(requestBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer your-proxy-token")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var result AsyncResponse
json.Unmarshal(body, &result)
fmt.Printf("Request ID: %s\n", result.RequestID)
}import java.net.http.*;
import java.net.URI;
import com.google.gson.*;
public class AsyncRequest {
public static void main(String[] args) throws Exception {
String json = "{"
+ "\"event\": \"user.created\","
+ "\"data\": {"
+ "\"id\": \"user_123\","
+ "\"email\": \"john@example.com\""
+ "}"
+ "}";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://us-east-1.requestrocket.com/async/abc123/webhooks"))
.header("Content-Type", "application/json")
.header("Authorization", "Bearer your-proxy-token")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
JsonObject jsonResponse = JsonParser.parseString(response.body()).getAsJsonObject();
String requestId = jsonResponse.get("requestId").getAsString();
System.out.println("Request ID: " + requestId);
}
}curl -X POST "https://us-east-1.requestrocket.com/async/abc123/webhooks" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-proxy-token" \
-d '{
"event": "user.created",
"data": {
"id": "user_123",
"email": "john@example.com"
}
}'Response Format
When you submit a request to the async endpoint, you receive an immediate response indicating the request has been queued:
Successful Queuing
{
"status": "queued",
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"message": "Your request has been queued for processing."
}Response Fields
| Field | Type | Description |
|---|---|---|
status | string | Request status (typically "queued") |
requestId | string | UUID v4 identifier for tracking |
message | string | Human-readable status message |
Tracking Request Status
Use the requestId to check the status of your async request via the Core API:
curl -X GET "https://api.requestrocket.com/requests/{requestId}" \
-H "Authorization: {your_user_token}"Learn more about the Requests endpoint →
Request Status Values
| Status | Description |
|---|---|
queued | Request accepted and waiting to be processed |
processing | Currently being processed |
completed | Successfully processed |
failed | Failed after all retries |
retrying | Failed but will be retried |
Retry Logic
The Async API implements intelligent retry with exponential backoff and jitter:
Retry Policy
- Maximum Retries: 10 attempts
- Time Window: Up to 15 minutes
- Strategy: Exponential backoff with jitter
- Transient Errors Only: Only specific error codes trigger retries
If you require more than 10 retries or a longer time window, please contact our support team.
Error Handling
Non-Retriable Errors
If there's a problem with your request (invalid payload, authentication failure, etc.), RequestRocket will:
- Log the error with telemetry data
- Not retry the request
- Mark the request as
failed
Retriable (Transient) Errors
RequestRocket automatically retries these HTTP status codes:
Standard HTTP Transient Errors
408 - Request Timeout
429 - Too Many Requests (rate limiting)
500 - Internal Server Error
502 - Bad Gateway
503 - Service Unavailable
504 - Gateway Timeout
507 - Insufficient Storage
509 - Bandwidth Limit ExceededCloudflare-Specific Errors
520 - Web server returns unknown error
521 - Web server is down
522 - Connection timed out
523 - Origin is unreachable
524 - A timeout occurred
525 - SSL handshake failed
526 - Invalid SSL certificate
530 - Origin DNS errorNon-Standard Transient Codes
598 - Network read timeout (nginx)
599 - Network connect timeout (nginx)If the target API returns any of these codes, RequestRocket will automatically retry with exponential backoff.
Response Headers
Just like the Proxy API, the Async API adds custom headers to responses:
requestrocket-proxy-code: Status of proxy authenticationrequestrocket-proxy-message: Human-readable descriptionrequestrocket-proxy-warning: Warning messages about account status
When you retrieve request results, the stored response will include these headers to help you understand what happened during processing.
View complete response headers documentation →
Request Flow
Use Cases
Webhooks
Perfect for sending webhooks where immediate response isn't needed:
async function sendWebhook(event, data) {
const response = await fetch(asyncEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${proxyToken}`
},
body: JSON.stringify({ event, data })
});
const result = await response.json();
// Store requestId for tracking
await db.webhooks.create({
requestId: result.requestId,
event,
status: 'queued'
});
}Batch Operations
Process large batches with automatic retry:
async function processBatch(items) {
const requests = items.map(item =>
fetch(asyncEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${proxyToken}`
},
body: JSON.stringify(item)
})
);
const responses = await Promise.all(requests);
const requestIds = await Promise.all(
responses.map(r => r.json())
);
return requestIds.map(r => r.requestId);
}Unreliable Networks
For mobile apps or unreliable connections:
async function syncData(data) {
try {
const response = await fetch(asyncEndpoint, {
method: 'POST',
headers: headers,
body: JSON.stringify(data),
timeout: 5000 // Short timeout for mobile
});
if (response.ok) {
const result = await response.json();
// Save requestId for later tracking
localStorage.setItem('lastSyncId', result.requestId);
return result.requestId;
}
} catch (error) {
// Network error - try again later
console.error('Sync failed, will retry');
}
}Data Migration
Migrate data with confidence:
def migrate_records(records):
"""Migrate records with automatic retry"""
request_ids = []
for record in records:
response = requests.post(
async_endpoint,
headers=headers,
json=record
)
if response.ok:
result = response.json()
request_ids.append(result['requestId'])
print(f"Queued: {result['requestId']}")
return request_ids
# Later: Check status of migrations
def check_migration_status(request_ids):
for req_id in request_ids:
status = requests.get(
f"https://api.requestrocket.com/requests/{req_id}",
headers={'Authorization': user_token}
)
print(f"{req_id}: {status.json()['status']}")Timeouts
- Queue Acceptance: Immediate (< 1 second)
- Processing Window: Up to 15 minutes with retries
- Single Attempt: 30 seconds per retry attempt
Comparison: Async API vs Proxy API
| Feature | Async API | Proxy API |
|---|---|---|
| Response | Immediate queue ACK | Actual target response |
| Retry | Automatic (10x) | Manual in client |
| Use For | Webhooks, batches | Real-time data |
| Tracking | Request ID | N/A |
| Best For | Reliability | Latency |
| Timeout | 15 min total | 30-60 seconds |