curl --request POST \
--url https://sandbox.api.meet-oj.com/partner/v0/submissions/{submission_id}/decision \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--data '
{
"offer": {
"items": [
{
"amount": 123,
"rate": 123,
"term_months": 123,
"number_of_payments": 123,
"payment_amount": 123,
"total_payback": 123,
"origination_fee": 123,
"notes": "<string>"
}
],
"conditions": [],
"expires_at": "2023-11-07T05:31:56Z"
},
"reasons": [
{
"reason": "Historical DSCR 1.18 after our adjustment for the one-time deposit in March",
"gate_key": "min_dscr"
}
],
"decided_by": "<string>",
"note": "<string>"
}
'import requests
url = "https://sandbox.api.meet-oj.com/partner/v0/submissions/{submission_id}/decision"
payload = {
"offer": {
"items": [
{
"amount": 123,
"rate": 123,
"term_months": 123,
"number_of_payments": 123,
"payment_amount": 123,
"total_payback": 123,
"origination_fee": 123,
"notes": "<string>"
}
],
"conditions": [],
"expires_at": "2023-11-07T05:31:56Z"
},
"reasons": [
{
"reason": "Historical DSCR 1.18 after our adjustment for the one-time deposit in March",
"gate_key": "min_dscr"
}
],
"decided_by": "<string>",
"note": "<string>"
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
offer: {
items: [
{
amount: 123,
rate: 123,
term_months: 123,
number_of_payments: 123,
payment_amount: 123,
total_payback: 123,
origination_fee: 123,
notes: '<string>'
}
],
conditions: [],
expires_at: '2023-11-07T05:31:56Z'
},
reasons: [
{
reason: 'Historical DSCR 1.18 after our adjustment for the one-time deposit in March',
gate_key: 'min_dscr'
}
],
decided_by: '<string>',
note: '<string>'
})
};
fetch('https://sandbox.api.meet-oj.com/partner/v0/submissions/{submission_id}/decision', 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://sandbox.api.meet-oj.com/partner/v0/submissions/{submission_id}/decision",
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([
'offer' => [
'items' => [
[
'amount' => 123,
'rate' => 123,
'term_months' => 123,
'number_of_payments' => 123,
'payment_amount' => 123,
'total_payback' => 123,
'origination_fee' => 123,
'notes' => '<string>'
]
],
'conditions' => [
],
'expires_at' => '2023-11-07T05:31:56Z'
],
'reasons' => [
[
'reason' => 'Historical DSCR 1.18 after our adjustment for the one-time deposit in March',
'gate_key' => 'min_dscr'
]
],
'decided_by' => '<string>',
'note' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"Idempotency-Key: <idempotency-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://sandbox.api.meet-oj.com/partner/v0/submissions/{submission_id}/decision"
payload := strings.NewReader("{\n \"offer\": {\n \"items\": [\n {\n \"amount\": 123,\n \"rate\": 123,\n \"term_months\": 123,\n \"number_of_payments\": 123,\n \"payment_amount\": 123,\n \"total_payback\": 123,\n \"origination_fee\": 123,\n \"notes\": \"<string>\"\n }\n ],\n \"conditions\": [],\n \"expires_at\": \"2023-11-07T05:31:56Z\"\n },\n \"reasons\": [\n {\n \"reason\": \"Historical DSCR 1.18 after our adjustment for the one-time deposit in March\",\n \"gate_key\": \"min_dscr\"\n }\n ],\n \"decided_by\": \"<string>\",\n \"note\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
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://sandbox.api.meet-oj.com/partner/v0/submissions/{submission_id}/decision")
.header("Idempotency-Key", "<idempotency-key>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"offer\": {\n \"items\": [\n {\n \"amount\": 123,\n \"rate\": 123,\n \"term_months\": 123,\n \"number_of_payments\": 123,\n \"payment_amount\": 123,\n \"total_payback\": 123,\n \"origination_fee\": 123,\n \"notes\": \"<string>\"\n }\n ],\n \"conditions\": [],\n \"expires_at\": \"2023-11-07T05:31:56Z\"\n },\n \"reasons\": [\n {\n \"reason\": \"Historical DSCR 1.18 after our adjustment for the one-time deposit in March\",\n \"gate_key\": \"min_dscr\"\n }\n ],\n \"decided_by\": \"<string>\",\n \"note\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox.api.meet-oj.com/partner/v0/submissions/{submission_id}/decision")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"offer\": {\n \"items\": [\n {\n \"amount\": 123,\n \"rate\": 123,\n \"term_months\": 123,\n \"number_of_payments\": 123,\n \"payment_amount\": 123,\n \"total_payback\": 123,\n \"origination_fee\": 123,\n \"notes\": \"<string>\"\n }\n ],\n \"conditions\": [],\n \"expires_at\": \"2023-11-07T05:31:56Z\"\n },\n \"reasons\": [\n {\n \"reason\": \"Historical DSCR 1.18 after our adjustment for the one-time deposit in March\",\n \"gate_key\": \"min_dscr\"\n }\n ],\n \"decided_by\": \"<string>\",\n \"note\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "sub_01K5X9E5F6",
"referral_id": "<string>",
"program_id": "<string>",
"status": "awaiting_review",
"submitted_at": "2023-11-07T05:31:56Z",
"object": "submission",
"business": {
"legal_name": "<string>",
"city": "<string>",
"state": "<string>"
},
"requested_amount": 123,
"package": {
"fit_id": "<string>",
"playbook_version": 123,
"documents": [
{
"document_id": "<string>",
"type": "bank_statement",
"period": "<string>",
"url": "<string>"
}
],
"receipts_url": "<string>",
"human_review": true
},
"hosted_review_url": "<string>",
"decision": {
"outcome": "offer",
"offer_id": "<string>",
"reasons": [
{
"gate_key": "<string>",
"reason": "<string>"
}
],
"decided_by": "<string>",
"decided_at": "2023-11-07T05:31:56Z"
},
"funded": {
"amount": 123,
"funded_at": "2023-11-07T05:31:56Z",
"lender_loan_id": "<string>"
},
"updated_at": "2023-11-07T05:31:56Z"
}{
"type": "https://api.meet-oj.com/problems/duplicate-external-id",
"title": "Referral already exists",
"status": 409,
"code": "invalid_request",
"request_id": "req_01K5X4A9M2",
"detail": "A referral with external_id cust_8842 was created on 2026-09-20 as ref_01K5X3K7Q2.",
"instance": "/partner/v0/referrals",
"param": "<string>"
}{
"type": "https://api.meet-oj.com/problems/duplicate-external-id",
"title": "Referral already exists",
"status": 409,
"code": "invalid_request",
"request_id": "req_01K5X4A9M2",
"detail": "A referral with external_id cust_8842 was created on 2026-09-20 as ref_01K5X3K7Q2.",
"instance": "/partner/v0/referrals",
"param": "<string>"
}{
"type": "https://api.meet-oj.com/problems/duplicate-external-id",
"title": "Referral already exists",
"status": 409,
"code": "invalid_request",
"request_id": "req_01K5X4A9M2",
"detail": "A referral with external_id cust_8842 was created on 2026-09-20 as ref_01K5X3K7Q2.",
"instance": "/partner/v0/referrals",
"param": "<string>"
}Record a decision
Records the outcome of your review. An offer creates an Offer on the referral in your name, and the
borrower accepts it on O.J.’s screen, in the partner’s product or on a hosted page. A decline records your
reasons for O.J.’s records; they are not shown to the partner or the borrower, who sees that you declined and
that you will send a notice. O.J. never makes this decision; it only records yours. Adverse-action notices are
yours to send.
curl --request POST \
--url https://sandbox.api.meet-oj.com/partner/v0/submissions/{submission_id}/decision \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--data '
{
"offer": {
"items": [
{
"amount": 123,
"rate": 123,
"term_months": 123,
"number_of_payments": 123,
"payment_amount": 123,
"total_payback": 123,
"origination_fee": 123,
"notes": "<string>"
}
],
"conditions": [],
"expires_at": "2023-11-07T05:31:56Z"
},
"reasons": [
{
"reason": "Historical DSCR 1.18 after our adjustment for the one-time deposit in March",
"gate_key": "min_dscr"
}
],
"decided_by": "<string>",
"note": "<string>"
}
'import requests
url = "https://sandbox.api.meet-oj.com/partner/v0/submissions/{submission_id}/decision"
payload = {
"offer": {
"items": [
{
"amount": 123,
"rate": 123,
"term_months": 123,
"number_of_payments": 123,
"payment_amount": 123,
"total_payback": 123,
"origination_fee": 123,
"notes": "<string>"
}
],
"conditions": [],
"expires_at": "2023-11-07T05:31:56Z"
},
"reasons": [
{
"reason": "Historical DSCR 1.18 after our adjustment for the one-time deposit in March",
"gate_key": "min_dscr"
}
],
"decided_by": "<string>",
"note": "<string>"
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
offer: {
items: [
{
amount: 123,
rate: 123,
term_months: 123,
number_of_payments: 123,
payment_amount: 123,
total_payback: 123,
origination_fee: 123,
notes: '<string>'
}
],
conditions: [],
expires_at: '2023-11-07T05:31:56Z'
},
reasons: [
{
reason: 'Historical DSCR 1.18 after our adjustment for the one-time deposit in March',
gate_key: 'min_dscr'
}
],
decided_by: '<string>',
note: '<string>'
})
};
fetch('https://sandbox.api.meet-oj.com/partner/v0/submissions/{submission_id}/decision', 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://sandbox.api.meet-oj.com/partner/v0/submissions/{submission_id}/decision",
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([
'offer' => [
'items' => [
[
'amount' => 123,
'rate' => 123,
'term_months' => 123,
'number_of_payments' => 123,
'payment_amount' => 123,
'total_payback' => 123,
'origination_fee' => 123,
'notes' => '<string>'
]
],
'conditions' => [
],
'expires_at' => '2023-11-07T05:31:56Z'
],
'reasons' => [
[
'reason' => 'Historical DSCR 1.18 after our adjustment for the one-time deposit in March',
'gate_key' => 'min_dscr'
]
],
'decided_by' => '<string>',
'note' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"Idempotency-Key: <idempotency-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://sandbox.api.meet-oj.com/partner/v0/submissions/{submission_id}/decision"
payload := strings.NewReader("{\n \"offer\": {\n \"items\": [\n {\n \"amount\": 123,\n \"rate\": 123,\n \"term_months\": 123,\n \"number_of_payments\": 123,\n \"payment_amount\": 123,\n \"total_payback\": 123,\n \"origination_fee\": 123,\n \"notes\": \"<string>\"\n }\n ],\n \"conditions\": [],\n \"expires_at\": \"2023-11-07T05:31:56Z\"\n },\n \"reasons\": [\n {\n \"reason\": \"Historical DSCR 1.18 after our adjustment for the one-time deposit in March\",\n \"gate_key\": \"min_dscr\"\n }\n ],\n \"decided_by\": \"<string>\",\n \"note\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
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://sandbox.api.meet-oj.com/partner/v0/submissions/{submission_id}/decision")
.header("Idempotency-Key", "<idempotency-key>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"offer\": {\n \"items\": [\n {\n \"amount\": 123,\n \"rate\": 123,\n \"term_months\": 123,\n \"number_of_payments\": 123,\n \"payment_amount\": 123,\n \"total_payback\": 123,\n \"origination_fee\": 123,\n \"notes\": \"<string>\"\n }\n ],\n \"conditions\": [],\n \"expires_at\": \"2023-11-07T05:31:56Z\"\n },\n \"reasons\": [\n {\n \"reason\": \"Historical DSCR 1.18 after our adjustment for the one-time deposit in March\",\n \"gate_key\": \"min_dscr\"\n }\n ],\n \"decided_by\": \"<string>\",\n \"note\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox.api.meet-oj.com/partner/v0/submissions/{submission_id}/decision")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"offer\": {\n \"items\": [\n {\n \"amount\": 123,\n \"rate\": 123,\n \"term_months\": 123,\n \"number_of_payments\": 123,\n \"payment_amount\": 123,\n \"total_payback\": 123,\n \"origination_fee\": 123,\n \"notes\": \"<string>\"\n }\n ],\n \"conditions\": [],\n \"expires_at\": \"2023-11-07T05:31:56Z\"\n },\n \"reasons\": [\n {\n \"reason\": \"Historical DSCR 1.18 after our adjustment for the one-time deposit in March\",\n \"gate_key\": \"min_dscr\"\n }\n ],\n \"decided_by\": \"<string>\",\n \"note\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "sub_01K5X9E5F6",
"referral_id": "<string>",
"program_id": "<string>",
"status": "awaiting_review",
"submitted_at": "2023-11-07T05:31:56Z",
"object": "submission",
"business": {
"legal_name": "<string>",
"city": "<string>",
"state": "<string>"
},
"requested_amount": 123,
"package": {
"fit_id": "<string>",
"playbook_version": 123,
"documents": [
{
"document_id": "<string>",
"type": "bank_statement",
"period": "<string>",
"url": "<string>"
}
],
"receipts_url": "<string>",
"human_review": true
},
"hosted_review_url": "<string>",
"decision": {
"outcome": "offer",
"offer_id": "<string>",
"reasons": [
{
"gate_key": "<string>",
"reason": "<string>"
}
],
"decided_by": "<string>",
"decided_at": "2023-11-07T05:31:56Z"
},
"funded": {
"amount": 123,
"funded_at": "2023-11-07T05:31:56Z",
"lender_loan_id": "<string>"
},
"updated_at": "2023-11-07T05:31:56Z"
}{
"type": "https://api.meet-oj.com/problems/duplicate-external-id",
"title": "Referral already exists",
"status": 409,
"code": "invalid_request",
"request_id": "req_01K5X4A9M2",
"detail": "A referral with external_id cust_8842 was created on 2026-09-20 as ref_01K5X3K7Q2.",
"instance": "/partner/v0/referrals",
"param": "<string>"
}{
"type": "https://api.meet-oj.com/problems/duplicate-external-id",
"title": "Referral already exists",
"status": 409,
"code": "invalid_request",
"request_id": "req_01K5X4A9M2",
"detail": "A referral with external_id cust_8842 was created on 2026-09-20 as ref_01K5X3K7Q2.",
"instance": "/partner/v0/referrals",
"param": "<string>"
}{
"type": "https://api.meet-oj.com/problems/duplicate-external-id",
"title": "Referral already exists",
"status": 409,
"code": "invalid_request",
"request_id": "req_01K5X4A9M2",
"detail": "A referral with external_id cust_8842 was created on 2026-09-20 as ref_01K5X3K7Q2.",
"instance": "/partner/v0/referrals",
"param": "<string>"
}Authorizations
One client per partner per environment. Access tokens expire after 15 minutes. Scopes are granted per client. Sandbox clients use https://sandbox.api.meet-oj.com/oauth/token.
Headers
IETF Idempotency-Key semantics (draft-ietf-httpapi-idempotency-key-header). Send a fresh unique value
(a UUID) with every new request. A retry with the same key and the same payload returns the original
response with the header Idempotent-Replayed: true. The same key with a different payload is rejected with
422 and code idempotency_key_reused. Keys are kept for 24 hours.
255Path Parameters
The submission id, from GET /programs/{program_id}/submissions or the submission.awaiting_review event.
Body
Your decision on a submission. For an offer, give the terms. O.J. creates the Offer and asks the borrower to accept it. For a decline, give your reasons, tied to your program's rules where they apply. They are kept for O.J.'s records and not shown to the partner or the borrower.
Response
The submission with the decision recorded
A referral that O.J. has submitted to your program, with the package your reviewer needs. package links
to every document, the calculations and the evidence receipts, and names the rules version the file was
checked against. hosted_review_url is a page where a reviewer can read the package and record the
decision without any integration. status moves from awaiting_review to offer or declined, and then
to funded when you report funding.
"sub_01K5X9E5F6"
awaiting_review, offer, declined, withdrawn, funded "submission"Show child attributes
Show child attributes
A dollar amount expressed in whole US cents, so $85,000.00 is 8500000. Cents avoid rounding errors that decimals cause in some languages.
Show child attributes
Show child attributes
For your reviewer. A magic link that expires and is renewed on each read.
Show child attributes
Show child attributes
Show child attributes
Show child attributes

