Validate document uploads before import
Creates or reuses a document validation job for CSV-mapped document imports without attaching files to records. The endpoint can validate direct multipart files or files already staged in an upload session. Requires admin file access through user.permissions.
curl --request POST \
--url https://api.gratona.com/v1/admin/import_files/{type}/{program_id}/validate-documents \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form csv_filename=imports/documents.csv \
--form csv_unique_field_column=0 \
--form csv_filename_column=1 \
--form csv_permission_column=2 \
--form unique_field=hys_id \
--form create_thumbnails=false \
--form upload_session_id=01HV7W4XW4N8Z3J7A2Y4C9R6K2 \
--form 'files=<string>'import requests
url = "https://api.gratona.com/v1/admin/import_files/{type}/{program_id}/validate-documents"
payload = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_filename\"\r\n\r\nimports/documents.csv\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_unique_field_column\"\r\n\r\n0\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_filename_column\"\r\n\r\n1\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_permission_column\"\r\n\r\n2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"unique_field\"\r\n\r\nhys_id\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"create_thumbnails\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"upload_session_id\"\r\n\r\n01HV7W4XW4N8Z3J7A2Y4C9R6K2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"\r\n\r\n<string>\r\n-----011000010111000001101001--"
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "multipart/form-data"
}
response = requests.post(url, data=payload, headers=headers)
print(response.text)const form = new FormData();
form.append('csv_filename', 'imports/documents.csv');
form.append('csv_unique_field_column', '0');
form.append('csv_filename_column', '1');
form.append('csv_permission_column', '2');
form.append('unique_field', 'hys_id');
form.append('create_thumbnails', 'false');
form.append('upload_session_id', '01HV7W4XW4N8Z3J7A2Y4C9R6K2');
form.append('files', '<string>');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.gratona.com/v1/admin/import_files/{type}/{program_id}/validate-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.gratona.com/v1/admin/import_files/{type}/{program_id}/validate-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=\"csv_filename\"\r\n\r\nimports/documents.csv\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_unique_field_column\"\r\n\r\n0\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_filename_column\"\r\n\r\n1\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_permission_column\"\r\n\r\n2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"unique_field\"\r\n\r\nhys_id\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"create_thumbnails\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"upload_session_id\"\r\n\r\n01HV7W4XW4N8Z3J7A2Y4C9R6K2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"\r\n\r\n<string>\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$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.gratona.com/v1/admin/import_files/{type}/{program_id}/validate-documents"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_filename\"\r\n\r\nimports/documents.csv\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_unique_field_column\"\r\n\r\n0\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_filename_column\"\r\n\r\n1\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_permission_column\"\r\n\r\n2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"unique_field\"\r\n\r\nhys_id\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"create_thumbnails\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"upload_session_id\"\r\n\r\n01HV7W4XW4N8Z3J7A2Y4C9R6K2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.gratona.com/v1/admin/import_files/{type}/{program_id}/validate-documents")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_filename\"\r\n\r\nimports/documents.csv\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_unique_field_column\"\r\n\r\n0\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_filename_column\"\r\n\r\n1\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_permission_column\"\r\n\r\n2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"unique_field\"\r\n\r\nhys_id\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"create_thumbnails\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"upload_session_id\"\r\n\r\n01HV7W4XW4N8Z3J7A2Y4C9R6K2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/admin/import_files/{type}/{program_id}/validate-documents")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_filename\"\r\n\r\nimports/documents.csv\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_unique_field_column\"\r\n\r\n0\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_filename_column\"\r\n\r\n1\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_permission_column\"\r\n\r\n2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"unique_field\"\r\n\r\nhys_id\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"create_thumbnails\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"upload_session_id\"\r\n\r\n01HV7W4XW4N8Z3J7A2Y4C9R6K2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"message": "Document validation has been queued.",
"validation_job_id": 124
}{
"message": "Not Found",
"status": "error"
}{
"errors": {},
"status": "error",
"message": "The given data was invalid."
}{
"message": "Something went wrong. Please try again.",
"status": "error",
"error": "invalid_request",
"code": "DONOR_NOT_FOUND"
}Authorizations
Passport bearer token authentication for legacy admin sessions.
Path Parameters
Required path value identifying whether documents will later attach to recipients or donors. Accepted values are entity and donor; invalid values return 422.
entity, donor Required program ID used to scope validation and later processing for the current client.
Body
Required string. S3 filename of the CSV mapping file.
"imports/documents.csv"
Required numeric zero-based CSV column index containing the unique field value.
x >= 00
Required numeric zero-based CSV column index containing document filenames.
x >= 01
Required numeric zero-based CSV column index containing file permissions.
x >= 02
Required string. Field key used to match each CSV row to a recipient or donor.
"hys_id"
Optional boolean. Requests thumbnail generation during import when applicable.
false
Nullable string. When present, claims files from an import upload session instead of reading multipart files.
"01HV7W4XW4N8Z3J7A2Y4C9R6K2"
Multipart document uploads required when upload_session_id is not supplied.
curl --request POST \
--url https://api.gratona.com/v1/admin/import_files/{type}/{program_id}/validate-documents \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form csv_filename=imports/documents.csv \
--form csv_unique_field_column=0 \
--form csv_filename_column=1 \
--form csv_permission_column=2 \
--form unique_field=hys_id \
--form create_thumbnails=false \
--form upload_session_id=01HV7W4XW4N8Z3J7A2Y4C9R6K2 \
--form 'files=<string>'import requests
url = "https://api.gratona.com/v1/admin/import_files/{type}/{program_id}/validate-documents"
payload = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_filename\"\r\n\r\nimports/documents.csv\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_unique_field_column\"\r\n\r\n0\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_filename_column\"\r\n\r\n1\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_permission_column\"\r\n\r\n2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"unique_field\"\r\n\r\nhys_id\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"create_thumbnails\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"upload_session_id\"\r\n\r\n01HV7W4XW4N8Z3J7A2Y4C9R6K2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"\r\n\r\n<string>\r\n-----011000010111000001101001--"
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "multipart/form-data"
}
response = requests.post(url, data=payload, headers=headers)
print(response.text)const form = new FormData();
form.append('csv_filename', 'imports/documents.csv');
form.append('csv_unique_field_column', '0');
form.append('csv_filename_column', '1');
form.append('csv_permission_column', '2');
form.append('unique_field', 'hys_id');
form.append('create_thumbnails', 'false');
form.append('upload_session_id', '01HV7W4XW4N8Z3J7A2Y4C9R6K2');
form.append('files', '<string>');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.gratona.com/v1/admin/import_files/{type}/{program_id}/validate-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.gratona.com/v1/admin/import_files/{type}/{program_id}/validate-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=\"csv_filename\"\r\n\r\nimports/documents.csv\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_unique_field_column\"\r\n\r\n0\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_filename_column\"\r\n\r\n1\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_permission_column\"\r\n\r\n2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"unique_field\"\r\n\r\nhys_id\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"create_thumbnails\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"upload_session_id\"\r\n\r\n01HV7W4XW4N8Z3J7A2Y4C9R6K2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"\r\n\r\n<string>\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$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.gratona.com/v1/admin/import_files/{type}/{program_id}/validate-documents"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_filename\"\r\n\r\nimports/documents.csv\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_unique_field_column\"\r\n\r\n0\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_filename_column\"\r\n\r\n1\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_permission_column\"\r\n\r\n2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"unique_field\"\r\n\r\nhys_id\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"create_thumbnails\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"upload_session_id\"\r\n\r\n01HV7W4XW4N8Z3J7A2Y4C9R6K2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.gratona.com/v1/admin/import_files/{type}/{program_id}/validate-documents")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_filename\"\r\n\r\nimports/documents.csv\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_unique_field_column\"\r\n\r\n0\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_filename_column\"\r\n\r\n1\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_permission_column\"\r\n\r\n2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"unique_field\"\r\n\r\nhys_id\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"create_thumbnails\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"upload_session_id\"\r\n\r\n01HV7W4XW4N8Z3J7A2Y4C9R6K2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/admin/import_files/{type}/{program_id}/validate-documents")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_filename\"\r\n\r\nimports/documents.csv\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_unique_field_column\"\r\n\r\n0\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_filename_column\"\r\n\r\n1\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"csv_permission_column\"\r\n\r\n2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"unique_field\"\r\n\r\nhys_id\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"create_thumbnails\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"upload_session_id\"\r\n\r\n01HV7W4XW4N8Z3J7A2Y4C9R6K2\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"message": "Document validation has been queued.",
"validation_job_id": 124
}{
"message": "Not Found",
"status": "error"
}{
"errors": {},
"status": "error",
"message": "The given data was invalid."
}{
"message": "Something went wrong. Please try again.",
"status": "error",
"error": "invalid_request",
"code": "DONOR_NOT_FOUND"
}