Download bulk status report
Download the detailed status report for a completed bulk charge schedule creation job. The report includes the original CSV data with additional columns showing the creation status and any error messages for each row.
Request Parametersโ
Responsesโ
200
Report downloadedReturns a CSV file containing the status report. The response Content-Type is text/csv.
- All original columns from the uploaded CSV
status- Row processing status (success or failed)schedule_id- Created schedule ID (schd_*) for successful rowserror_code- Error code for failed rowserror_message- Detailed error description for failed rows
customer_key,customer,card,amount,description,every,period,days_of_month,start_date,end_date,status,schedule_id,error_code,error_message sub_001,cust_test_abc123,,100000,Monthly plan,1,month,1,2025-02-01,2026-01-31,success,schd_test_xyz789,, sub_002,cust_test_invalid,,50000,Basic plan,1,month,15,2025-02-01,,failed,,invalid_customer,Customer not found
400
Bad requestRequest validation failed. Check the error message for details.
- Invalid recurring_id format
- Job is not yet completed (still pending or processing)
401
UnauthorizedAuthentication failed. Invalid or missing API key.
- Missing Authorization header
- Invalid secret key
- Using public key instead of secret key
- Incorrect HTTP Basic Auth format
404
Not foundBulk creation job not found or report not available.
- Invalid recurring_id
- Job belongs to different account
- Mixing test and live mode keys
- Report has expired (older than 30 days)
5xx
Server errorServer-side error occurred. These are rare but should be handled gracefully.
- Retry the request with exponential backoff
- Check status.omise.co for service incidents
- See Error Handling for detailed guidance
Code samplesโ
- cURL
- Ruby
- Python
- Node.js
- PHP
- Java
- C#
- Go
# Download bulk creation status report
curl https://api.omise.co/recurring_exports/recr_test_5xuy4w91xqz7d1w9u0t/download \
-u skey_test_5xuy4w91xqz7d1w9u0t: \
-o status_report.csv
require 'omise'
require 'net/http'
require 'uri'
Omise.api_key = 'skey_test_5xuy4w91xqz7d1w9u0t'
recurring_id = 'recr_test_5xuy4w91xqz7d1w9u0t'
uri = URI("https://api.omise.co/recurring_exports/#{recurring_id}/download")
request = Net::HTTP::Get.new(uri)
request.basic_auth(Omise.api_key, '')
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
# Save to file
File.open('status_report.csv', 'w') do |file|
file.write(response.body)
end
puts "Report saved to status_report.csv"
import omise
import requests
omise.api_secret = 'skey_test_5xuy4w91xqz7d1w9u0t'
recurring_id = 'recr_test_5xuy4w91xqz7d1w9u0t'
response = requests.get(
f'https://api.omise.co/recurring_exports/{recurring_id}/download',
auth=(omise.api_secret, '')
)
# Save to file
with open('status_report.csv', 'wb') as f:
f.write(response.content)
print("Report saved to status_report.csv")
# Or parse and process the CSV
import csv
import io
reader = csv.DictReader(io.StringIO(response.text))
for row in reader:
if row['status'] == 'failed':
print(f"Failed: {row['customer_key']} - {row['error_message']}")
const omise = require('omise')({
secretKey: 'skey_test_5xuy4w91xqz7d1w9u0t'
});
const axios = require('axios');
const fs = require('fs');
const recurringId = 'recr_test_5xuy4w91xqz7d1w9u0t';
const response = await axios.get(
`https://api.omise.co/recurring_exports/${recurringId}/download`,
{
auth: {
username: 'skey_test_5xuy4w91xqz7d1w9u0t',
password: ''
},
responseType: 'text'
}
);
// Save to file
fs.writeFileSync('status_report.csv', response.data);
console.log('Report saved to status_report.csv');
// Or parse and process
const Papa = require('papaparse');
const parsed = Papa.parse(response.data, { header: true });
parsed.data.forEach(row => {
if (row.status === 'failed') {
console.log(`Failed: ${row.customer_key} - ${row.error_message}`);
}
});
<?php
define('OMISE_SECRET_KEY', 'skey_test_5xuy4w91xqz7d1w9u0t');
$recurring_id = 'recr_test_5xuy4w91xqz7d1w9u0t';
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.omise.co/recurring_exports/{$recurring_id}/download",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERPWD => OMISE_SECRET_KEY . ':'
]);
$response = curl_exec($curl);
curl_close($curl);
// Save to file
file_put_contents('status_report.csv', $response);
echo "Report saved to status_report.csv\n";
// Or parse and process
$lines = explode("\n", $response);
$header = str_getcsv(array_shift($lines));
foreach ($lines as $line) {
if (empty($line)) continue;
$row = array_combine($header, str_getcsv($line));
if ($row['status'] === 'failed') {
echo "Failed: {$row['customer_key']} - {$row['error_message']}\n";
}
}
import java.io.FileOutputStream;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Base64;
HttpClient client = HttpClient.newHttpClient();
String recurringId = "recr_test_5xuy4w91xqz7d1w9u0t";
String auth = Base64.getEncoder().encodeToString("skey_test_5xuy4w91xqz7d1w9u0t:".getBytes());
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.omise.co/recurring_exports/" + recurringId + "/download"))
.header("Authorization", "Basic " + auth)
.GET()
.build();
HttpResponse<byte[]> response = client.send(request, HttpResponse.BodyHandlers.ofByteArray());
// Save to file
try (FileOutputStream fos = new FileOutputStream("status_report.csv")) {
fos.write(response.body());
}
System.out.println("Report saved to status_report.csv");
using System.Net.Http;
using System.Net.Http.Headers;
using System.IO;
var client = new HttpClient();
var credentials = Convert.ToBase64String(
System.Text.Encoding.ASCII.GetBytes("skey_test_5xuy4w91xqz7d1w9u0t:")
);
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", credentials);
var recurringId = "recr_test_5xuy4w91xqz7d1w9u0t";
var response = await client.GetAsync(
$"https://api.omise.co/recurring_exports/{recurringId}/download"
);
var content = await response.Content.ReadAsByteArrayAsync();
// Save to file
await File.WriteAllBytesAsync("status_report.csv", content);
Console.WriteLine("Report saved to status_report.csv");
package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
recurringId := "recr_test_5xuy4w91xqz7d1w9u0t"
req, _ := http.NewRequest("GET",
"https://api.omise.co/recurring_exports/"+recurringId+"/download", nil)
req.SetBasicAuth("skey_test_5xuy4w91xqz7d1w9u0t", "")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
// Save to file
file, _ := os.Create("status_report.csv")
defer file.Close()
io.Copy(file, resp.Body)
fmt.Println("Report saved to status_report.csv")
}
Processing the Status Reportโ
After downloading the report, you can process it to handle failed rows:
import csv
def process_status_report(filepath):
successful = []
failed = []
with open(filepath, 'r') as f:
reader = csv.DictReader(f)
for row in reader:
if row['status'] == 'success':
successful.append({
'customer_key': row['customer_key'],
'schedule_id': row['schedule_id']
})
else:
failed.append({
'customer_key': row['customer_key'],
'error_code': row['error_code'],
'error_message': row['error_message']
})
print(f"Successful: {len(successful)}")
print(f"Failed: {len(failed)}")
# Retry failed rows or notify relevant teams
for fail in failed:
print(f" - {fail['customer_key']}: {fail['error_message']}")
return successful, failed
successful, failed = process_status_report('status_report.csv')
Error and result codesโ
Row Status Valuesโ
| Status | Description |
|---|---|
success | Schedule created successfully |
failed | Schedule creation failed |
Common Error Codes in Reportโ
| Code | Description | Resolution |
|---|---|---|
invalid_customer | Customer ID not found | Verify customer exists and is active |
no_card_attached | Customer has no payment card | Attach a card to the customer |
invalid_card | Card ID not found or expired | Use a valid card or remove to use default |
invalid_amount | Amount is zero, negative, or invalid | Provide positive integer amount |
invalid_period | Period value not recognized | Use day, week, or month |
invalid_days_of_month | Invalid day values | Use values 1-28 |
invalid_date_format | Date format not recognized | Use YYYY-MM-DD format |
start_date_in_past | Start date is in the past | Use current or future date |
end_date_before_start | End date is before start date | Ensure end date is after start date |
duplicate_schedule | Schedule already exists for customer | Check for existing schedules |
Try it outโ
...Loading...