Get presigned URL to upload supporting document
curl --request POST \
--url https://gateway.useyala.com/v1/payout-api/payouts/documents/upload-url \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"filename": "invoice.pdf",
"contentType": "application/pdf"
}
'import requests
url = "https://gateway.useyala.com/v1/payout-api/payouts/documents/upload-url"
payload = {
"filename": "invoice.pdf",
"contentType": "application/pdf"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({filename: 'invoice.pdf', contentType: 'application/pdf'})
};
fetch('https://gateway.useyala.com/v1/payout-api/payouts/documents/upload-url', 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://gateway.useyala.com/v1/payout-api/payouts/documents/upload-url",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'filename' => 'invoice.pdf',
'contentType' => 'application/pdf'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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://gateway.useyala.com/v1/payout-api/payouts/documents/upload-url"
payload := strings.NewReader("{\n \"filename\": \"invoice.pdf\",\n \"contentType\": \"application/pdf\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://gateway.useyala.com/v1/payout-api/payouts/documents/upload-url")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"filename\": \"invoice.pdf\",\n \"contentType\": \"application/pdf\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://gateway.useyala.com/v1/payout-api/payouts/documents/upload-url")
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["Content-Type"] = 'application/json'
request.body = "{\n \"filename\": \"invoice.pdf\",\n \"contentType\": \"application/pdf\"\n}"
response = http.request(request)
puts response.read_bodyPayouts
Get Document Upload URL
Get a presigned URL to upload an invoice directly to S3 before or after creating a payout.
POST
/
v1
/
payout-api
/
payouts
/
documents
/
upload-url
Get presigned URL to upload supporting document
curl --request POST \
--url https://gateway.useyala.com/v1/payout-api/payouts/documents/upload-url \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"filename": "invoice.pdf",
"contentType": "application/pdf"
}
'import requests
url = "https://gateway.useyala.com/v1/payout-api/payouts/documents/upload-url"
payload = {
"filename": "invoice.pdf",
"contentType": "application/pdf"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({filename: 'invoice.pdf', contentType: 'application/pdf'})
};
fetch('https://gateway.useyala.com/v1/payout-api/payouts/documents/upload-url', 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://gateway.useyala.com/v1/payout-api/payouts/documents/upload-url",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'filename' => 'invoice.pdf',
'contentType' => 'application/pdf'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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://gateway.useyala.com/v1/payout-api/payouts/documents/upload-url"
payload := strings.NewReader("{\n \"filename\": \"invoice.pdf\",\n \"contentType\": \"application/pdf\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://gateway.useyala.com/v1/payout-api/payouts/documents/upload-url")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"filename\": \"invoice.pdf\",\n \"contentType\": \"application/pdf\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://gateway.useyala.com/v1/payout-api/payouts/documents/upload-url")
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["Content-Type"] = 'application/json'
request.body = "{\n \"filename\": \"invoice.pdf\",\n \"contentType\": \"application/pdf\"\n}"
response = http.request(request)
puts response.read_bodyOverview
Returns a presigned PUT URL so your server can upload an invoice directly to Yala’s private S3 bucket. Yala does not accept file bytes on this endpoint—only metadata (filename, contentType).
After uploading to S3, use the returned documentUrl on:
POST /initiateassupportingDocument, orPATCH /:id/documentsin thedocumentsarray
Read Uploading Supporting Documents for the full 3-step flow: call Yala, upload to S3, then call Yala again with
documentUrl.Upload flow (3 steps)
| Step | Where | Action |
|---|---|---|
| 1 | Yala API | POST /documents/upload-url returns uploadUrl and documentUrl |
| 2 | Amazon S3 | PUT file bytes to uploadUrl (not Yala) |
| 3 | Yala API | POST /initiate or PATCH /:id/documents with documentUrl |
Request
POST /v1/payout-api/payouts/documents/upload-url HTTP/1.1
Host: gateway.staging.useyala.com
Content-Type: application/json
x-api-key: <YOUR_API_KEY>
{
"filename": "invoice.pdf",
"contentType": "application/pdf"
}
Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
filename | string | Yes | Original filename (basename only, e.g. invoice.pdf) |
contentType | string | Yes | MIME type: application/pdf, image/jpeg, image/jpg, or image/png |
Response
{
"documentId": "550e8400-e29b-41d4-a716-446655440000",
"uploadUrl": "https://yala-payout-api-docs-staging.s3.us-east-1.amazonaws.com/staging/payout-api/.../invoice.pdf?X-Amz-Algorithm=...",
"documentUrl": "https://yala-payout-api-docs-staging.s3.us-east-1.amazonaws.com/staging/payout-api/<businessId>/<documentId>/invoice.pdf",
"expiresAt": "2024-01-20T10:15:00.000Z",
"method": "PUT",
"headers": {
"Content-Type": "application/pdf"
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
documentId | string (UUID) | Document identifier (embedded in S3 key) |
uploadUrl | string | Presigned URL for one-time PUT to S3 (~15 min TTL) |
documentUrl | string | Stable HTTPS URL — pass this to initiate/PATCH after upload succeeds |
expiresAt | string (ISO 8601) | When uploadUrl expires |
method | string | Always PUT |
headers | object | Headers required on the PUT request (e.g. Content-Type) |
Upload the file to S3
curl -X PUT "<uploadUrl>" \
-H "Content-Type: application/pdf" \
--data-binary @invoice.pdf
const { uploadUrl, documentUrl, headers } = await uploadUrlResponse.json();
const file = await fs.readFile('invoice.pdf');
const putResult = await fetch(uploadUrl, {
method: 'PUT',
headers,
body: file,
});
if (!putResult.ok) {
throw new Error('S3 upload failed');
}
// Use documentUrl on initiate or PATCH — not uploadUrl
Error Responses
400 Bad Request
Invalid filename or unsupportedcontentType.
401 Unauthorized
Invalid or missing API key.Related
⌘I