curl --request POST \
--url https://production.hifi.com/v3/rfis/{rfiId}/submissions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data @- <<EOF
{
"items": [
{
"requestItemId": "3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34",
"fileId": "file_7bV1aLcs3Kf9dQ2mNpXwZ"
},
{
"requestItemId": "3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34",
"fileId": "file_9aB0xY4mNpXwZ7bV1aLdt"
},
{
"requestItemId": "6b2d4a81-7c05-4e39-8f1a-2d9c3e7b5041",
"answerText": "Salary from the user's employer, with payslips attached."
}
]
}
EOFimport requests
url = "https://production.hifi.com/v3/rfis/{rfiId}/submissions"
payload = { "items": [
{
"requestItemId": "3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34",
"fileId": "file_7bV1aLcs3Kf9dQ2mNpXwZ"
},
{
"requestItemId": "3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34",
"fileId": "file_9aB0xY4mNpXwZ7bV1aLdt"
},
{
"requestItemId": "6b2d4a81-7c05-4e39-8f1a-2d9c3e7b5041",
"answerText": "Salary from the user's employer, with payslips attached."
}
] }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
items: [
{
requestItemId: '3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34',
fileId: 'file_7bV1aLcs3Kf9dQ2mNpXwZ'
},
{
requestItemId: '3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34',
fileId: 'file_9aB0xY4mNpXwZ7bV1aLdt'
},
{
requestItemId: '6b2d4a81-7c05-4e39-8f1a-2d9c3e7b5041',
answerText: 'Salary from the user\'s employer, with payslips attached.'
}
]
})
};
fetch('https://production.hifi.com/v3/rfis/{rfiId}/submissions', 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://production.hifi.com/v3/rfis/{rfiId}/submissions",
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([
'items' => [
[
'requestItemId' => '3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34',
'fileId' => 'file_7bV1aLcs3Kf9dQ2mNpXwZ'
],
[
'requestItemId' => '3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34',
'fileId' => 'file_9aB0xY4mNpXwZ7bV1aLdt'
],
[
'requestItemId' => '6b2d4a81-7c05-4e39-8f1a-2d9c3e7b5041',
'answerText' => 'Salary from the user\'s employer, with payslips attached.'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://production.hifi.com/v3/rfis/{rfiId}/submissions"
payload := strings.NewReader("{\n \"items\": [\n {\n \"requestItemId\": \"3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34\",\n \"fileId\": \"file_7bV1aLcs3Kf9dQ2mNpXwZ\"\n },\n {\n \"requestItemId\": \"3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34\",\n \"fileId\": \"file_9aB0xY4mNpXwZ7bV1aLdt\"\n },\n {\n \"requestItemId\": \"6b2d4a81-7c05-4e39-8f1a-2d9c3e7b5041\",\n \"answerText\": \"Salary from the user's employer, with payslips attached.\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://production.hifi.com/v3/rfis/{rfiId}/submissions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"items\": [\n {\n \"requestItemId\": \"3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34\",\n \"fileId\": \"file_7bV1aLcs3Kf9dQ2mNpXwZ\"\n },\n {\n \"requestItemId\": \"3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34\",\n \"fileId\": \"file_9aB0xY4mNpXwZ7bV1aLdt\"\n },\n {\n \"requestItemId\": \"6b2d4a81-7c05-4e39-8f1a-2d9c3e7b5041\",\n \"answerText\": \"Salary from the user's employer, with payslips attached.\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://production.hifi.com/v3/rfis/{rfiId}/submissions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"items\": [\n {\n \"requestItemId\": \"3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34\",\n \"fileId\": \"file_7bV1aLcs3Kf9dQ2mNpXwZ\"\n },\n {\n \"requestItemId\": \"3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34\",\n \"fileId\": \"file_9aB0xY4mNpXwZ7bV1aLdt\"\n },\n {\n \"requestItemId\": \"6b2d4a81-7c05-4e39-8f1a-2d9c3e7b5041\",\n \"answerText\": \"Salary from the user's employer, with payslips attached.\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"rfiId": "rfi_5Kf9dQ2mNpXwZ7bV1aLcs",
"roundId": "rfir_2mNpXwZ7bV1aLcs3Kf9dQ",
"round": 1,
"status": "submitted",
"submittedAt": "2026-07-03T09:12:44.000Z",
"responseCount": 3
}{
"type": "VALIDATION_ERROR",
"message": "One or more fields are invalid or missing.",
"fields": [
{
"code": "invalid_value",
"message": "Must be a valid email address",
"field": "email"
}
]
}{
"type": "UNAUTHORIZED",
"message": "Authentication required"
}{
"type": "RESOURCE_NOT_FOUND",
"message": "<string>",
"fields": [
{
"code": "<string>",
"message": "<string>",
"field": "<string>"
}
]
}{
"type": "RESOURCE_CONFLICT",
"message": "Resource already exists or conflicts with current state"
}{
"type": "ACTION_NOT_ALLOWED",
"message": "This action is not allowed"
}{
"type": "INTERNAL_SERVER_ERROR",
"message": "An internal server error occurred"
}Submit a response to an RFI
Answer the current round of a request for information. Each entry in items replies to one request item by its requestItemId with exactly one of fileId or answerText, and any file must be uploaded through the files endpoint first. Every item marked required must be answered, and a round accepts only one submission.
curl --request POST \
--url https://production.hifi.com/v3/rfis/{rfiId}/submissions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data @- <<EOF
{
"items": [
{
"requestItemId": "3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34",
"fileId": "file_7bV1aLcs3Kf9dQ2mNpXwZ"
},
{
"requestItemId": "3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34",
"fileId": "file_9aB0xY4mNpXwZ7bV1aLdt"
},
{
"requestItemId": "6b2d4a81-7c05-4e39-8f1a-2d9c3e7b5041",
"answerText": "Salary from the user's employer, with payslips attached."
}
]
}
EOFimport requests
url = "https://production.hifi.com/v3/rfis/{rfiId}/submissions"
payload = { "items": [
{
"requestItemId": "3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34",
"fileId": "file_7bV1aLcs3Kf9dQ2mNpXwZ"
},
{
"requestItemId": "3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34",
"fileId": "file_9aB0xY4mNpXwZ7bV1aLdt"
},
{
"requestItemId": "6b2d4a81-7c05-4e39-8f1a-2d9c3e7b5041",
"answerText": "Salary from the user's employer, with payslips attached."
}
] }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
items: [
{
requestItemId: '3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34',
fileId: 'file_7bV1aLcs3Kf9dQ2mNpXwZ'
},
{
requestItemId: '3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34',
fileId: 'file_9aB0xY4mNpXwZ7bV1aLdt'
},
{
requestItemId: '6b2d4a81-7c05-4e39-8f1a-2d9c3e7b5041',
answerText: 'Salary from the user\'s employer, with payslips attached.'
}
]
})
};
fetch('https://production.hifi.com/v3/rfis/{rfiId}/submissions', 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://production.hifi.com/v3/rfis/{rfiId}/submissions",
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([
'items' => [
[
'requestItemId' => '3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34',
'fileId' => 'file_7bV1aLcs3Kf9dQ2mNpXwZ'
],
[
'requestItemId' => '3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34',
'fileId' => 'file_9aB0xY4mNpXwZ7bV1aLdt'
],
[
'requestItemId' => '6b2d4a81-7c05-4e39-8f1a-2d9c3e7b5041',
'answerText' => 'Salary from the user\'s employer, with payslips attached.'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://production.hifi.com/v3/rfis/{rfiId}/submissions"
payload := strings.NewReader("{\n \"items\": [\n {\n \"requestItemId\": \"3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34\",\n \"fileId\": \"file_7bV1aLcs3Kf9dQ2mNpXwZ\"\n },\n {\n \"requestItemId\": \"3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34\",\n \"fileId\": \"file_9aB0xY4mNpXwZ7bV1aLdt\"\n },\n {\n \"requestItemId\": \"6b2d4a81-7c05-4e39-8f1a-2d9c3e7b5041\",\n \"answerText\": \"Salary from the user's employer, with payslips attached.\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://production.hifi.com/v3/rfis/{rfiId}/submissions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"items\": [\n {\n \"requestItemId\": \"3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34\",\n \"fileId\": \"file_7bV1aLcs3Kf9dQ2mNpXwZ\"\n },\n {\n \"requestItemId\": \"3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34\",\n \"fileId\": \"file_9aB0xY4mNpXwZ7bV1aLdt\"\n },\n {\n \"requestItemId\": \"6b2d4a81-7c05-4e39-8f1a-2d9c3e7b5041\",\n \"answerText\": \"Salary from the user's employer, with payslips attached.\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://production.hifi.com/v3/rfis/{rfiId}/submissions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"items\": [\n {\n \"requestItemId\": \"3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34\",\n \"fileId\": \"file_7bV1aLcs3Kf9dQ2mNpXwZ\"\n },\n {\n \"requestItemId\": \"3f7c1e90-2a4b-4d61-9c0e-5b8f2d6a1e34\",\n \"fileId\": \"file_9aB0xY4mNpXwZ7bV1aLdt\"\n },\n {\n \"requestItemId\": \"6b2d4a81-7c05-4e39-8f1a-2d9c3e7b5041\",\n \"answerText\": \"Salary from the user's employer, with payslips attached.\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"rfiId": "rfi_5Kf9dQ2mNpXwZ7bV1aLcs",
"roundId": "rfir_2mNpXwZ7bV1aLcs3Kf9dQ",
"round": 1,
"status": "submitted",
"submittedAt": "2026-07-03T09:12:44.000Z",
"responseCount": 3
}{
"type": "VALIDATION_ERROR",
"message": "One or more fields are invalid or missing.",
"fields": [
{
"code": "invalid_value",
"message": "Must be a valid email address",
"field": "email"
}
]
}{
"type": "UNAUTHORIZED",
"message": "Authentication required"
}{
"type": "RESOURCE_NOT_FOUND",
"message": "<string>",
"fields": [
{
"code": "<string>",
"message": "<string>",
"field": "<string>"
}
]
}{
"type": "RESOURCE_CONFLICT",
"message": "Resource already exists or conflicts with current state"
}{
"type": "ACTION_NOT_ALLOWED",
"message": "This action is not allowed"
}{
"type": "INTERNAL_SERVER_ERROR",
"message": "An internal server error occurred"
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Public ID of the request for information (prefixed with rfi_)
Body
The replies making up one submission.
One entry per reply.
1 - 200 elementsShow child attributes
Show child attributes
Response
Success
Confirmation that a submission was recorded.
Public ID of the request that was answered (prefixed with rfi_).
"rfi_5Kf9dQ2mNpXwZ7bV1aLcs"
Public ID of the round that was answered (prefixed with rfir_).
"rfir_2mNpXwZ7bV1aLcs3Kf9dQ"
Attempt number that was answered.
1
Status of the request after the submission.
submitted "submitted"
When the submission was recorded.
"2026-07-03T09:12:44.000Z"
Number of replies recorded, which may exceed the number of request items answered.
5