Bulk create charge schedules
Upload a CSV file to create multiple charge schedules in a single operation. This endpoint initiates an asynchronous bulk creation job and returns a recurring_id that you can use to monitor progress and download status reports.
Request Parametersโ
Required - 1 fieldRequired Parameters
`file`FILE(required)
CSV file containing charge schedule data. Each row represents one schedule to create.
CSV StructureCSV Columns
`customer_key`STRING(required)
Unique identifier for tracking this row in status reports. Can be any string meaningful to your system.
`customer`STRING(required)
Customer ID (cust_*) who will be charged. Customer must have at least one card attached.
`card`STRING(optional)
Specific card ID to charge. If not specified, the customer's default card will be used.
`amount`INTEGER(required)
Charge amount in smallest currency unit (e.g., satang for THB, cents for USD).
`description`STRING(optional)
Description that will appear on each charge created by this schedule.
`every`INTEGER(required)
Frequency multiplier. For example, every=2 with period=month means every 2 months.
`period`STRING(required)
Time unit for the schedule frequency.
`days_of_month`STRING(optional)
For monthly schedules: specific days to charge (1-28). Use semicolon to specify multiple days.
`start_date`STRING(optional)
Schedule start date in YYYY-MM-DD format. Defaults to today if not specified.
`end_date`STRING(optional)
Schedule end date in YYYY-MM-DD format. Schedule will expire after this date.
Responsesโ
200
Upload acceptedCSV file accepted and bulk creation job has been queued. Use the returned recurring_id to monitor progress.
Response includes:
object- Always "recurring_export"id- Recurring export ID (recr_*) for tracking the joblivemode- Whether this is a live mode operationlocation- API path to monitor the jobstate- Initial state (typically "pending")total_rows- Number of rows detected in CSVprocessed_rows- Number of rows processed (0 initially)successful_rows- Number of successful creations (0 initially)failed_rows- Number of failed creations (0 initially)created_at- Job creation timestamp
400
Bad requestRequest validation failed. Check the error message for details.
Common causes:
- File missing or empty
- Invalid CSV format or structure
- Missing required columns in CSV header
- File exceeds 10MB size limit
- CSV contains more than 10,000 rows
401
UnauthorizedAuthentication failed. Invalid or missing API key.
Common causes:
- Missing Authorization header
- Invalid secret key
- Using public key instead of secret key
- Incorrect HTTP Basic Auth format
404
Not foundEndpoint not found or feature not enabled.
Common causes:
- Bulk operations feature not enabled for account
- Incorrect API endpoint URL
5xx
Server errorServer-side error occurred. These are rare but should be handled gracefully.
How to handle:
- 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
# Upload CSV file to create multiple charge schedules
curl https://api.omise.co/schedules/upload \
-X POST \
-u skey_test_5xuy4w91xqz7d1w9u0t: \
-F "file=@/path/to/schedules.csv"
require 'omise'
require 'net/http'
require 'uri'
Omise.api_key = 'skey_test_5xuy4w91xqz7d1w9u0t'
uri = URI('https://api.omise.co/schedules/upload')
request = Net::HTTP::Post.new(uri)
request.basic_auth(Omise.api_key, '')
form_data = [['file', File.open('/path/to/schedules.csv')]]
request.set_form(form_data, 'multipart/form-data')
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
result = JSON.parse(response.body)
puts "Job ID: #{result['id']}"
import omise
import requests
omise.api_secret = 'skey_test_5xuy4w91xqz7d1w9u0t'
with open('/path/to/schedules.csv', 'rb') as csv_file:
response = requests.post(
'https://api.omise.co/schedules/upload',
auth=(omise.api_secret, ''),
files={'file': csv_file}
)
result = response.json()
print(f"Job ID: {result['id']}")
print(f"Total rows: {result['total_rows']}")
const omise = require('omise')({
secretKey: 'skey_test_5xuy4w91xqz7d1w9u0t'
});
const fs = require('fs');
const FormData = require('form-data');
const axios = require('axios');
const form = new FormData();
form.append('file', fs.createReadStream('/path/to/schedules.csv'));
const response = await axios.post('https://api.omise.co/schedules/upload', form, {
auth: {
username: 'skey_test_5xuy4w91xqz7d1w9u0t',
password: ''
},
headers: form.getHeaders()
});
console.log('Job ID:', response.data.id);
console.log('Total rows:', response.data.total_rows);
<?php
define('OMISE_SECRET_KEY', 'skey_test_5xuy4w91xqz7d1w9u0t');
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'https://api.omise.co/schedules/upload',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_USERPWD => OMISE_SECRET_KEY . ':',
CURLOPT_POSTFIELDS => [
'file' => new CURLFile('/path/to/schedules.csv', 'text/csv', 'schedules.csv')
]
]);
$response = curl_exec($curl);
curl_close($curl);
$result = json_decode($response, true);
echo "Job ID: " . $result['id'] . "\n";
echo "Total rows: " . $result['total_rows'] . "\n";
import java.io.File;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.util.Base64;
HttpClient client = HttpClient.newHttpClient();
String boundary = "----WebKitFormBoundary" + System.currentTimeMillis();
File csvFile = new File("/path/to/schedules.csv");
byte[] fileBytes = Files.readAllBytes(csvFile.toPath());
String body = "--" + boundary + "\r\n" +
"Content-Disposition: form-data; name=\"file\"; filename=\"schedules.csv\"\r\n" +
"Content-Type: text/csv\r\n\r\n" +
new String(fileBytes) + "\r\n" +
"--" + boundary + "--";
String auth = Base64.getEncoder().encodeToString("skey_test_5xuy4w91xqz7d1w9u0t:".getBytes());
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.omise.co/schedules/upload"))
.header("Authorization", "Basic " + auth)
.header("Content-Type", "multipart/form-data; boundary=" + boundary)
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
using System.Net.Http;
using System.Net.Http.Headers;
var client = new HttpClient();
var credentials = Convert.ToBase64String(
System.Text.Encoding.ASCII.GetBytes("skey_test_5xuy4w91xqz7d1w9u0t:")
);
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", credentials);
using var content = new MultipartFormDataContent();
using var fileStream = File.OpenRead("/path/to/schedules.csv");
var fileContent = new StreamContent(fileStream);
fileContent.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
content.Add(fileContent, "file", "schedules.csv");
var response = await client.PostAsync("https://api.omise.co/schedules/upload", content);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
)
func main() {
file, _ := os.Open("/path/to/schedules.csv")
defer file.Close()
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, _ := writer.CreateFormFile("file", "schedules.csv")
io.Copy(part, file)
writer.Close()
req, _ := http.NewRequest("POST", "https://api.omise.co/schedules/upload", body)
req.SetBasicAuth("skey_test_5xuy4w91xqz7d1w9u0t", "")
req.Header.Set("Content-Type", writer.FormDataContentType())
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Job ID: %s\n", result["id"])
}
Example CSV Fileโ
customer_key,customer,card,amount,description,every,period,days_of_month,start_date,end_date
sub_001,cust_test_5xuy4w91xqz7d1w9u0t,,100000,Monthly premium plan,1,month,1,2025-02-01,2026-01-31
sub_002,cust_test_5xuy4w91xqz7d1w9u0t,card_test_5xuy4w91xqz7d1w9u0t,50000,Basic subscription,1,month,15,2025-02-01,
sub_003,cust_test_5xuy4w91xqz7d1w9u0t,,200000,Enterprise plan,1,month,1;15,2025-02-01,2025-12-31
Error and result codesโ
Common Error Codesโ
| Code | Description | Resolution |
|---|---|---|
authentication_failure | Invalid API key | Verify your secret key is correct |
invalid_file | File is missing or invalid | Ensure file is a valid CSV |
file_too_large | File exceeds 10MB limit | Split into smaller files |
invalid_csv_structure | Missing required columns | Check CSV header row |
too_many_rows | CSV exceeds 10,000 rows | Split into multiple files |
CSV Row Error Codesโ
| Code | Description | Resolution |
|---|---|---|
invalid_customer | Customer ID not found | Verify customer exists |
no_card_attached | Customer has no card | Attach a card to customer first |
invalid_card | Card ID not found or expired | Use valid card ID |
invalid_amount | Amount is invalid | Use positive integer |
invalid_period | Period value invalid | Use day, week, or month |
invalid_date_format | Date format invalid | Use YYYY-MM-DD format |
API Credentials
Try it outโ
Required - 1 fields
Your IP:
...Loading...