Upload an attachment
Stores a supporting document for the entity and returns an opaque id you can pass as attachmentId when creating a payment. Upload once, reference from as many payments as you need.
Send multipart/form-data with the document in a part named file. PDF, JPEG and PNG are accepted, up to 8 MB. The bytes are not readable back through this API — only the metadata below is returned.
The main reason to use this: some international destinations will not accept a payment without a supporting document, and POST /payments then fails with 400 ATTACHMENT_REQUIRED. See attachmentId on the payment request.
const form = new FormData();
form.append('file', '<string>');
const options = {
method: 'POST',
headers: {'Melio-Entity-Id': '<melio-entity-id>', 'api-key': '<api-key>'}
};
options.body = form;
fetch('https://api.melio.com/v2/attachments', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.melio.com/v2/attachments"
files = { "file": ("example-file", open("example-file", "rb")) }
headers = {
"Melio-Entity-Id": "<melio-entity-id>",
"api-key": "<api-key>"
}
response = requests.post(url, files=files, headers=headers)
print(response.text)curl --request POST \
--url https://api.melio.com/v2/attachments \
--header 'Content-Type: multipart/form-data' \
--header 'Melio-Entity-Id: <melio-entity-id>' \
--header 'api-key: <api-key>' \
--form file=@example-fileHttpResponse<String> response = Unirest.post("https://api.melio.com/v2/attachments")
.header("Melio-Entity-Id", "<melio-entity-id>")
.header("api-key", "<api-key>")
.header("Content-Type", "multipart/form-data")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.melio.com/v2/attachments")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Melio-Entity-Id"] = '<melio-entity-id>'
request["api-key"] = '<api-key>'
request["Content-Type"] = 'multipart/form-data'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_bodypackage main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.melio.com/v2/attachments"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Melio-Entity-Id", "<melio-entity-id>")
req.Header.Add("api-key", "<api-key>")
req.Header.Add("Content-Type", "multipart/form-data")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"id": "att_9f8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"fileName": "invoice-2043.pdf",
"mimeType": "application/pdf",
"byteSize": 182734,
"createdAt": "2026-09-07T10:15:00.000Z"
}Headers
Response
Attachment stored.
A stored document. The bytes are write-only through this API; what comes back is the id to reference from a payment plus enough metadata to recognise which file it was.
const form = new FormData();
form.append('file', '<string>');
const options = {
method: 'POST',
headers: {'Melio-Entity-Id': '<melio-entity-id>', 'api-key': '<api-key>'}
};
options.body = form;
fetch('https://api.melio.com/v2/attachments', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.melio.com/v2/attachments"
files = { "file": ("example-file", open("example-file", "rb")) }
headers = {
"Melio-Entity-Id": "<melio-entity-id>",
"api-key": "<api-key>"
}
response = requests.post(url, files=files, headers=headers)
print(response.text)curl --request POST \
--url https://api.melio.com/v2/attachments \
--header 'Content-Type: multipart/form-data' \
--header 'Melio-Entity-Id: <melio-entity-id>' \
--header 'api-key: <api-key>' \
--form file=@example-fileHttpResponse<String> response = Unirest.post("https://api.melio.com/v2/attachments")
.header("Melio-Entity-Id", "<melio-entity-id>")
.header("api-key", "<api-key>")
.header("Content-Type", "multipart/form-data")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.melio.com/v2/attachments")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Melio-Entity-Id"] = '<melio-entity-id>'
request["api-key"] = '<api-key>'
request["Content-Type"] = 'multipart/form-data'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_bodypackage main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.melio.com/v2/attachments"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Melio-Entity-Id", "<melio-entity-id>")
req.Header.Add("api-key", "<api-key>")
req.Header.Add("Content-Type", "multipart/form-data")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"id": "att_9f8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"fileName": "invoice-2043.pdf",
"mimeType": "application/pdf",
"byteSize": 182734,
"createdAt": "2026-09-07T10:15:00.000Z"
}