Attach Documents
curl --request POST \
--url https://api.rolla.xyz/api/v1/external/payer-names/{payerNameId}/documents \
--header 'Content-Type: multipart/form-data' \
--header 'X-API-Key: <api-key>' \
--form 'documentDescriptions[0]=Certificate of incorporation' \
--form 'documentDescriptions[1]=Director ID' \
--form documents.items='@example-file'import requests
url = "https://api.rolla.xyz/api/v1/external/payer-names/{payerNameId}/documents"
files = { "documents.items": ("example-file", open("example-file", "rb")) }
payload = {
"documentDescriptions[0]": "Certificate of incorporation",
"documentDescriptions[1]": "Director ID"
}
headers = {"X-API-Key": "<api-key>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('documentDescriptions[0]', 'Certificate of incorporation');
form.append('documentDescriptions[1]', 'Director ID');
form.append('documents.items', '{
"fileName": "example-file"
}');
const options = {method: 'POST', headers: {'X-API-Key': '<api-key>'}};
options.body = form;
fetch('https://api.rolla.xyz/api/v1/external/payer-names/{payerNameId}/documents', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.rolla.xyz/api/v1/external/payer-names/{payerNameId}/documents",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documentDescriptions%5B0%5D\"\r\n\r\nCertificate of incorporation\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documentDescriptions%5B1%5D\"\r\n\r\nDirector ID\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documents.items\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Content-Type: multipart/form-data",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.rolla.xyz/api/v1/external/payer-names/{payerNameId}/documents"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documentDescriptions%5B0%5D\"\r\n\r\nCertificate of incorporation\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documentDescriptions%5B1%5D\"\r\n\r\nDirector ID\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documents.items\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.rolla.xyz/api/v1/external/payer-names/{payerNameId}/documents")
.header("X-API-Key", "<api-key>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documentDescriptions%5B0%5D\"\r\n\r\nCertificate of incorporation\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documentDescriptions%5B1%5D\"\r\n\r\nDirector ID\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documents.items\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.rolla.xyz/api/v1/external/payer-names/{payerNameId}/documents")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documentDescriptions%5B0%5D\"\r\n\r\nCertificate of incorporation\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documentDescriptions%5B1%5D\"\r\n\r\nDirector ID\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documents.items\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"status": 201,
"message": "Documents attached",
"success": true,
"data": {
"id": "9f8e7d6c-5b4a-4938-8271-0a1b2c3d4e5f",
"type": "business",
"name": "Acme Trading Ltd",
"firstName": null,
"lastName": null,
"registrationNumber": "RC1234567",
"registrationDate": "2019-04-02",
"country": "NG",
"address": {
"line1": "14 Marina Road",
"city": "Lagos",
"state": "Lagos",
"postalCode": "101001"
},
"status": "pending_review",
"isDefault": false,
"decisionNote": null,
"documents": [
{
"id": "2b3c4d5e-6f70-4812-9a3b-4c5d6e7f8091",
"fileName": "certificate-of-incorporation.pdf",
"description": "Certificate of incorporation",
"fileType": "application/pdf",
"fileSize": 284122,
"downloadUrl": "https://files.rolla.xyz/payer_name_docs/...",
"createdAt": "2026-09-03T10:20:00.000Z"
},
{
"id": "3c4d5e6f-7081-4923-ab4c-5d6e7f809112",
"fileName": "director-id.jpg",
"description": "Director ID",
"fileType": "image/jpeg",
"fileSize": 91233,
"downloadUrl": "https://files.rolla.xyz/payer_name_docs/...",
"createdAt": "2026-09-03T10:20:00.000Z"
}
],
"metadata": {
"vendor_id": "V-4471"
},
"createdAt": "2026-09-01T09:14:22.000Z",
"updatedAt": "2026-09-03T10:20:00.000Z"
}
}{
"status": 400,
"message": "No documents were provided"
}{
"status": 400,
"message": "Validation failed",
"code": "ACCOUNT_RESTRICTED",
"errors": [
{
"path": [
"amount"
],
"message": "amount must be a whole number of smallest currency units (e.g. cents)"
}
]
}{
"status": 403,
"message": "Payer names are not enabled for this account. Contact your Rolla account manager to turn them on.",
"code": "PAYER_NAMES_DISABLED"
}{
"status": 404,
"message": "Payer name not found"
}{
"status": 409,
"message": "Documents can only be added while a payer name is under review (status: approved)"
}Payer Names (Named Payouts)
Attach Documents
Adds supporting documents to a payer name that is still in review. Unlike an update, this does not reset the review status or clear the reviewer note. Documents cannot be added once a decision has been made.
POST
/
payer-names
/
{payerNameId}
/
documents
Attach Documents
curl --request POST \
--url https://api.rolla.xyz/api/v1/external/payer-names/{payerNameId}/documents \
--header 'Content-Type: multipart/form-data' \
--header 'X-API-Key: <api-key>' \
--form 'documentDescriptions[0]=Certificate of incorporation' \
--form 'documentDescriptions[1]=Director ID' \
--form documents.items='@example-file'import requests
url = "https://api.rolla.xyz/api/v1/external/payer-names/{payerNameId}/documents"
files = { "documents.items": ("example-file", open("example-file", "rb")) }
payload = {
"documentDescriptions[0]": "Certificate of incorporation",
"documentDescriptions[1]": "Director ID"
}
headers = {"X-API-Key": "<api-key>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('documentDescriptions[0]', 'Certificate of incorporation');
form.append('documentDescriptions[1]', 'Director ID');
form.append('documents.items', '{
"fileName": "example-file"
}');
const options = {method: 'POST', headers: {'X-API-Key': '<api-key>'}};
options.body = form;
fetch('https://api.rolla.xyz/api/v1/external/payer-names/{payerNameId}/documents', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.rolla.xyz/api/v1/external/payer-names/{payerNameId}/documents",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documentDescriptions%5B0%5D\"\r\n\r\nCertificate of incorporation\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documentDescriptions%5B1%5D\"\r\n\r\nDirector ID\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documents.items\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Content-Type: multipart/form-data",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.rolla.xyz/api/v1/external/payer-names/{payerNameId}/documents"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documentDescriptions%5B0%5D\"\r\n\r\nCertificate of incorporation\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documentDescriptions%5B1%5D\"\r\n\r\nDirector ID\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documents.items\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.rolla.xyz/api/v1/external/payer-names/{payerNameId}/documents")
.header("X-API-Key", "<api-key>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documentDescriptions%5B0%5D\"\r\n\r\nCertificate of incorporation\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documentDescriptions%5B1%5D\"\r\n\r\nDirector ID\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documents.items\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.rolla.xyz/api/v1/external/payer-names/{payerNameId}/documents")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documentDescriptions%5B0%5D\"\r\n\r\nCertificate of incorporation\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documentDescriptions%5B1%5D\"\r\n\r\nDirector ID\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"documents.items\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"status": 201,
"message": "Documents attached",
"success": true,
"data": {
"id": "9f8e7d6c-5b4a-4938-8271-0a1b2c3d4e5f",
"type": "business",
"name": "Acme Trading Ltd",
"firstName": null,
"lastName": null,
"registrationNumber": "RC1234567",
"registrationDate": "2019-04-02",
"country": "NG",
"address": {
"line1": "14 Marina Road",
"city": "Lagos",
"state": "Lagos",
"postalCode": "101001"
},
"status": "pending_review",
"isDefault": false,
"decisionNote": null,
"documents": [
{
"id": "2b3c4d5e-6f70-4812-9a3b-4c5d6e7f8091",
"fileName": "certificate-of-incorporation.pdf",
"description": "Certificate of incorporation",
"fileType": "application/pdf",
"fileSize": 284122,
"downloadUrl": "https://files.rolla.xyz/payer_name_docs/...",
"createdAt": "2026-09-03T10:20:00.000Z"
},
{
"id": "3c4d5e6f-7081-4923-ab4c-5d6e7f809112",
"fileName": "director-id.jpg",
"description": "Director ID",
"fileType": "image/jpeg",
"fileSize": 91233,
"downloadUrl": "https://files.rolla.xyz/payer_name_docs/...",
"createdAt": "2026-09-03T10:20:00.000Z"
}
],
"metadata": {
"vendor_id": "V-4471"
},
"createdAt": "2026-09-01T09:14:22.000Z",
"updatedAt": "2026-09-03T10:20:00.000Z"
}
}{
"status": 400,
"message": "No documents were provided"
}{
"status": 400,
"message": "Validation failed",
"code": "ACCOUNT_RESTRICTED",
"errors": [
{
"path": [
"amount"
],
"message": "amount must be a whole number of smallest currency units (e.g. cents)"
}
]
}{
"status": 403,
"message": "Payer names are not enabled for this account. Contact your Rolla account manager to turn them on.",
"code": "PAYER_NAMES_DISABLED"
}{
"status": 404,
"message": "Payer name not found"
}{
"status": 409,
"message": "Documents can only be added while a payer name is under review (status: approved)"
}Adds supporting documents to a payer name that is still in review — the usual answer to a reviewer asking for better evidence.
Repeat
Anything else is rejected with a
Example Request
curl -X POST "https://api.rolla.xyz/api/v1/external/payer-names/9f8e7d6c-5b4a-4938-8271-0a1b2c3d4e5f/documents" \
-H "X-API-Key: your_api_key_here" \
-F "documents=@certificate-of-incorporation.pdf" \
-F "documents=@director-id.jpg" \
-F "documentDescriptions=Certificate of incorporation" \
-F "documentDescriptions=Director ID"
documents once per file. documentDescriptions labels them positionally: the first description belongs to the first file. A file with no description is stored unlabelled.
Example Response
The full payer name, with the new documents included.{
"status": 201,
"message": "Documents attached",
"success": true,
"data": {
"id": "9f8e7d6c-5b4a-4938-8271-0a1b2c3d4e5f",
"type": "business",
"name": "Acme Trading Ltd",
"firstName": null,
"lastName": null,
"registrationNumber": "RC1234567",
"registrationDate": "2019-04-02",
"country": "NG",
"address": { "line1": "14 Marina Road", "city": "Lagos", "state": "Lagos", "postalCode": "101001" },
"status": "pending_review",
"isDefault": false,
"decisionNote": null,
"documents": [
{
"id": "2b3c4d5e-6f70-4812-9a3b-4c5d6e7f8091",
"fileName": "certificate-of-incorporation.pdf",
"description": "Certificate of incorporation",
"fileType": "application/pdf",
"fileSize": 284122,
"downloadUrl": "https://files.rolla.xyz/payer_name_docs/...",
"createdAt": "2026-09-03T10:20:00.000Z"
},
{
"id": "3c4d5e6f-7081-4923-ab4c-5d6e7f809112",
"fileName": "director-id.jpg",
"description": "Director ID",
"fileType": "image/jpeg",
"fileSize": 91233,
"downloadUrl": "https://files.rolla.xyz/payer_name_docs/...",
"createdAt": "2026-09-03T10:20:00.000Z"
}
],
"metadata": { "vendor_id": "V-4471" },
"createdAt": "2026-09-01T09:14:22.000Z",
"updatedAt": "2026-09-03T10:20:00.000Z"
}
}
Accepted files
| Constraint | Value |
|---|---|
| Formats | PDF, JPEG, PNG, Word (.doc, .docx) |
| Maximum size | 10MB per file |
| Count | No limit; attach as many as the review needs |
400, and no file in the call is stored.
Unlike an update, attaching documents does not reset the review status or clear the reviewer’s note. The name stays where it is, with more evidence on it.
Errors
| Status | Cause |
|---|---|
400 | No file was sent, or a file is too large or of an unsupported type |
403 | Named Payouts are not enabled for this account (code: PAYER_NAMES_DISABLED) |
404 | No such payer name on this account |
409 | The payer name is no longer in review, so documents can no longer be added |
Authorizations
Your Rolla API key
Path Parameters
The payer name id.
Body
multipart/form-data
Response
Documents attached. The full payer name is returned, with the new documents included.