curl --request POST \
--url https://api.flightlinehq.com/v1/reviews \
--header 'Content-Type: application/json' \
--data '
{
"documents": [
{
"content_type": "application/zip",
"filename": "full-case.zip",
"url": "https://files.example.com/signed/full-case.zip?sig=abc123"
}
],
"label": "Smith refinance",
"metadata": {
"branch": "austin",
"loan_officer": "jsmith"
},
"reference_id": "LN-2026-04-8812",
"review_type": "mortgage_v1"
}
'import requests
url = "https://api.flightlinehq.com/v1/reviews"
payload = {
"documents": [
{
"content_type": "application/zip",
"filename": "full-case.zip",
"url": "https://files.example.com/signed/full-case.zip?sig=abc123"
}
],
"label": "Smith refinance",
"metadata": {
"branch": "austin",
"loan_officer": "jsmith"
},
"reference_id": "LN-2026-04-8812",
"review_type": "mortgage_v1"
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
documents: [
{
content_type: 'application/zip',
filename: 'full-case.zip',
url: 'https://files.example.com/signed/full-case.zip?sig=abc123'
}
],
label: 'Smith refinance',
metadata: {branch: 'austin', loan_officer: 'jsmith'},
reference_id: 'LN-2026-04-8812',
review_type: 'mortgage_v1'
})
};
fetch('https://api.flightlinehq.com/v1/reviews', 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.flightlinehq.com/v1/reviews",
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([
'documents' => [
[
'content_type' => 'application/zip',
'filename' => 'full-case.zip',
'url' => 'https://files.example.com/signed/full-case.zip?sig=abc123'
]
],
'label' => 'Smith refinance',
'metadata' => [
'branch' => 'austin',
'loan_officer' => 'jsmith'
],
'reference_id' => 'LN-2026-04-8812',
'review_type' => 'mortgage_v1'
]),
CURLOPT_HTTPHEADER => [
"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://api.flightlinehq.com/v1/reviews"
payload := strings.NewReader("{\n \"documents\": [\n {\n \"content_type\": \"application/zip\",\n \"filename\": \"full-case.zip\",\n \"url\": \"https://files.example.com/signed/full-case.zip?sig=abc123\"\n }\n ],\n \"label\": \"Smith refinance\",\n \"metadata\": {\n \"branch\": \"austin\",\n \"loan_officer\": \"jsmith\"\n },\n \"reference_id\": \"LN-2026-04-8812\",\n \"review_type\": \"mortgage_v1\"\n}")
req, _ := http.NewRequest("POST", url, payload)
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://api.flightlinehq.com/v1/reviews")
.header("Content-Type", "application/json")
.body("{\n \"documents\": [\n {\n \"content_type\": \"application/zip\",\n \"filename\": \"full-case.zip\",\n \"url\": \"https://files.example.com/signed/full-case.zip?sig=abc123\"\n }\n ],\n \"label\": \"Smith refinance\",\n \"metadata\": {\n \"branch\": \"austin\",\n \"loan_officer\": \"jsmith\"\n },\n \"reference_id\": \"LN-2026-04-8812\",\n \"review_type\": \"mortgage_v1\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.flightlinehq.com/v1/reviews")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"documents\": [\n {\n \"content_type\": \"application/zip\",\n \"filename\": \"full-case.zip\",\n \"url\": \"https://files.example.com/signed/full-case.zip?sig=abc123\"\n }\n ],\n \"label\": \"Smith refinance\",\n \"metadata\": {\n \"branch\": \"austin\",\n \"loan_officer\": \"jsmith\"\n },\n \"reference_id\": \"LN-2026-04-8812\",\n \"review_type\": \"mortgage_v1\"\n}"
response = http.request(request)
puts response.read_body{
"created_at": "2026-05-30T17:00:00Z",
"document_count": 3,
"label": "Smith refinance",
"reference_id": "LN-2026-04-8812",
"report_available": false,
"review_id": "9b2c1f3a-4d5e-6789-abcd-ef0123456789",
"review_type": "mortgage_v1",
"sandbox": false,
"status": "processing",
"updated_at": "2026-05-30T17:00:05Z"
}{
"error": {
"code": "document_required",
"message": "At least one document is required."
}
}{
"error": {
"code": "missing_api_key",
"message": "Missing API key. Send 'Authorization: Bearer <key>'."
}
}{
"error": {
"code": "duplicate_reference_id",
"message": "A review with reference_id 'LN-2026-04-8812' already exists."
}
}{
"error": {
"code": "document_too_large",
"message": "File too large: full-case.zip"
}
}{
"error": {
"code": "invalid_request",
"message": "Invalid request body. Check field(s): documents.0.url."
}
}{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded. Retry with exponential backoff."
}
}Create Review
Create a review and ingest its documents in one call.
Accepts either multipart/form-data (file uploads) or
application/json (documents referenced by signed source URL).
Send an optional Idempotency-Key header to make the create safely
retryable: resending the SAME request with the SAME key returns the
ORIGINAL review (HTTP 200) instead of creating a duplicate (which would
re-run the expensive pipeline). Keys are scoped to the caller’s org.
curl --request POST \
--url https://api.flightlinehq.com/v1/reviews \
--header 'Content-Type: application/json' \
--data '
{
"documents": [
{
"content_type": "application/zip",
"filename": "full-case.zip",
"url": "https://files.example.com/signed/full-case.zip?sig=abc123"
}
],
"label": "Smith refinance",
"metadata": {
"branch": "austin",
"loan_officer": "jsmith"
},
"reference_id": "LN-2026-04-8812",
"review_type": "mortgage_v1"
}
'import requests
url = "https://api.flightlinehq.com/v1/reviews"
payload = {
"documents": [
{
"content_type": "application/zip",
"filename": "full-case.zip",
"url": "https://files.example.com/signed/full-case.zip?sig=abc123"
}
],
"label": "Smith refinance",
"metadata": {
"branch": "austin",
"loan_officer": "jsmith"
},
"reference_id": "LN-2026-04-8812",
"review_type": "mortgage_v1"
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
documents: [
{
content_type: 'application/zip',
filename: 'full-case.zip',
url: 'https://files.example.com/signed/full-case.zip?sig=abc123'
}
],
label: 'Smith refinance',
metadata: {branch: 'austin', loan_officer: 'jsmith'},
reference_id: 'LN-2026-04-8812',
review_type: 'mortgage_v1'
})
};
fetch('https://api.flightlinehq.com/v1/reviews', 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.flightlinehq.com/v1/reviews",
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([
'documents' => [
[
'content_type' => 'application/zip',
'filename' => 'full-case.zip',
'url' => 'https://files.example.com/signed/full-case.zip?sig=abc123'
]
],
'label' => 'Smith refinance',
'metadata' => [
'branch' => 'austin',
'loan_officer' => 'jsmith'
],
'reference_id' => 'LN-2026-04-8812',
'review_type' => 'mortgage_v1'
]),
CURLOPT_HTTPHEADER => [
"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://api.flightlinehq.com/v1/reviews"
payload := strings.NewReader("{\n \"documents\": [\n {\n \"content_type\": \"application/zip\",\n \"filename\": \"full-case.zip\",\n \"url\": \"https://files.example.com/signed/full-case.zip?sig=abc123\"\n }\n ],\n \"label\": \"Smith refinance\",\n \"metadata\": {\n \"branch\": \"austin\",\n \"loan_officer\": \"jsmith\"\n },\n \"reference_id\": \"LN-2026-04-8812\",\n \"review_type\": \"mortgage_v1\"\n}")
req, _ := http.NewRequest("POST", url, payload)
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://api.flightlinehq.com/v1/reviews")
.header("Content-Type", "application/json")
.body("{\n \"documents\": [\n {\n \"content_type\": \"application/zip\",\n \"filename\": \"full-case.zip\",\n \"url\": \"https://files.example.com/signed/full-case.zip?sig=abc123\"\n }\n ],\n \"label\": \"Smith refinance\",\n \"metadata\": {\n \"branch\": \"austin\",\n \"loan_officer\": \"jsmith\"\n },\n \"reference_id\": \"LN-2026-04-8812\",\n \"review_type\": \"mortgage_v1\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.flightlinehq.com/v1/reviews")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"documents\": [\n {\n \"content_type\": \"application/zip\",\n \"filename\": \"full-case.zip\",\n \"url\": \"https://files.example.com/signed/full-case.zip?sig=abc123\"\n }\n ],\n \"label\": \"Smith refinance\",\n \"metadata\": {\n \"branch\": \"austin\",\n \"loan_officer\": \"jsmith\"\n },\n \"reference_id\": \"LN-2026-04-8812\",\n \"review_type\": \"mortgage_v1\"\n}"
response = http.request(request)
puts response.read_body{
"created_at": "2026-05-30T17:00:00Z",
"document_count": 3,
"label": "Smith refinance",
"reference_id": "LN-2026-04-8812",
"report_available": false,
"review_id": "9b2c1f3a-4d5e-6789-abcd-ef0123456789",
"review_type": "mortgage_v1",
"sandbox": false,
"status": "processing",
"updated_at": "2026-05-30T17:00:05Z"
}{
"error": {
"code": "document_required",
"message": "At least one document is required."
}
}{
"error": {
"code": "missing_api_key",
"message": "Missing API key. Send 'Authorization: Bearer <key>'."
}
}{
"error": {
"code": "duplicate_reference_id",
"message": "A review with reference_id 'LN-2026-04-8812' already exists."
}
}{
"error": {
"code": "document_too_large",
"message": "File too large: full-case.zip"
}
}{
"error": {
"code": "invalid_request",
"message": "Invalid request body. Check field(s): documents.0.url."
}
}{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded. Retry with exponential backoff."
}
}Headers
Optional. A unique key (at most 255 characters) you choose for this create request. Resending the same request with the same key returns the ORIGINAL review (HTTP 200) instead of creating a duplicate, so the review pipeline runs exactly once. Keys are scoped to your organization. Distinct from 'reference_id', which rejects a duplicate with 409 rather than replaying.
Body
Create a review with either direct case-package uploads (multipart/form-data) or case packages referenced by signed source URL (application/json).
JSON body for POST /reviews (signed-source-URL variant).
The multipart/form-data variant carries the same logical fields as form
parts plus the file uploads; see reviews.create_review.
Case packages or documents to ingest by signed source URL.
Optional human-readable label shown in the dashboard.
500"Smith refinance"
Optional flat string->string metadata echoed back on reads.
Show child attributes
Show child attributes
{
"branch": "austin",
"loan_officer": "jsmith"
}
Your external identifier for this loan package (idempotency key).
255"LN-2026-04-8812"
Review template to run (maps to an internal schema).
1 - 100"mortgage_v1"
Response
Successful Response
A review, as seen by the customer.
Returned by POST /reviews (201) and GET /reviews/{id}.
Flightline's identifier for this review.
Customer-facing review lifecycle.
A deliberately coarse projection of the internal CaseStatus. Internal
states that are not meaningful to a customer (e.g. the admin-release gate
pending_review, the publication-blocker state) collapse to
processing so we never surface internal workflow detail or
verdict-adjacent signal before the publication gate passes.
queued, awaiting_documents, processing, completed, failed Number of documents ingested.
True once the report is released and retrievable.
True for sandbox (test-mode) reviews: canned results, no real analysis.

