Introduction
This documentation aims to provide all the information you need to work with our API.
<aside>As you scroll, you'll see code examples for working with the API in different programming languages in the dark area to the right (or as part of the content on mobile).
You can switch the language used with the tabs at the top right (or from the nav menu at the top left on mobile).</aside>
Authenticating requests
To authenticate requests, include an Authorization header with the value "Bearer {YOUR_AUTH_KEY}".
All authenticated endpoints are marked with a requires authentication badge in the documentation below.
You can ask the SOS Golpe support team to generate a token for you.
MED Request Files
API endpoints for managing MED request files
Upload a file or multiple files for a MED request
requires authentication
Example request:
curl --request POST \
"http://localhost/api/v1/med-requests/20/files" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "type=other"\
--form "types[]=audio-report"\
--form "file=@/tmp/phpm8co4po0se338rnskpQ" \
--form "files[]=@/tmp/phpauurvmp1ik18eYaJkcF" const url = new URL(
"http://localhost/api/v1/med-requests/20/files"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('type', 'other');
body.append('types[]', 'audio-report');
body.append('file', document.querySelector('input[name="file"]').files[0]);
body.append('files[]', document.querySelector('input[name="files[]"]').files[0]);
fetch(url, {
method: "POST",
headers,
body,
}).then(response => response.json());Example response (200):
{
"data": {
"id": 28,
"fraud_detail_id": 70,
"type": "occurrence-report",
"path": "eius",
"url": "https://signed.url?X-Amz-SignedParams=...",
"metadata": [],
"validations": {
"errors": []
},
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update a MED request file
requires authentication
Example request:
curl --request PUT \
"http://localhost/api/v1/files/16" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "type=occurrence-report"\
--form "file=@/tmp/phpsugiflpaifmb8GIJnBq" const url = new URL(
"http://localhost/api/v1/files/16"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('type', 'occurrence-report');
body.append('file', document.querySelector('input[name="file"]').files[0]);
fetch(url, {
method: "PUT",
headers,
body,
}).then(response => response.json());Example response (200):
{
"data": {
"id": 29,
"fraud_detail_id": 71,
"type": "occurrence-report",
"path": "eius",
"url": "https://signed.url?X-Amz-SignedParams=...",
"metadata": [],
"validations": {
"errors": []
},
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List MED request files.
requires authentication
Example request:
curl --request GET \
--get "http://localhost/api/v1/files?filters=%7B%22path%22%3A+%22file_path%22%7D&per_page=15&page=1" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost/api/v1/files"
);
const params = {
"filters": "{"path": "file_path"}",
"per_page": "15",
"page": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": 30,
"fraud_detail_id": 72,
"type": "occurrence-report",
"path": "adipisci",
"url": "https://signed.url?X-Amz-SignedParams=...",
"metadata": [],
"validations": {
"errors": []
},
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
{
"id": 31,
"fraud_detail_id": 73,
"type": "other",
"path": "odio",
"url": "https://signed.url?X-Amz-SignedParams=...",
"metadata": [],
"validations": {
"errors": []
},
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
MED request management
APIs for managing MED requests
List MED requests.
requires authentication
Example request:
curl --request GET \
--get "http://localhost/api/v1/med-requests?filters=%7B%22origin_customer_id%22%3A+1%2C+%22origin_bank_id%22%3A+1%7D&per_page=15&page=1" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost/api/v1/med-requests"
);
const params = {
"filters": "{"origin_customer_id": 1, "origin_bank_id": 1}",
"per_page": "15",
"page": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": 49,
"transaction_id": "E2E1757680",
"transaction_amount": "9736.93",
"transaction_time": "2025-07-11T18:20:53.000000Z",
"transaction_description": "Omnis autem et consequatur.",
"reporter_client_name": "Schultz Group",
"reporter_client_id": "7059720839",
"contested_participant_id": null,
"counterparty_client_name": "Fahey, Cartwright and Balistreri",
"counterparty_client_id": "0261536693",
"counterparty_client_key": "ac9e0973-adfe-32df-ade4-9b9752e8c6ad",
"protocol_id": "62b13b25-7887-3a6d-933d-9f63b76646b2",
"pix_auto": null,
"ispb": "04415490",
"client_id": null,
"client_since": "2025-07-21T18:20:53.000000Z",
"client_birth": null,
"autofraud_risk": null,
"latest_status": "requested",
"latest_refund_status": "pending",
"latest_refund_status_reason": null,
"situation_type": null,
"report_merge": false,
"category": "scam",
"sub_category": "scam_buy-hire",
"tactic": "scam_debt-charge_restore-credit",
"scam_checks": [
"scam-check_delivered-false-item"
],
"channels": [
"scammer_phone"
],
"items": [
"item_buy-other",
"item_developer"
],
"origin_channel": "whatsapp-unknown",
"is_over_60_optin": false,
"report": "Voluptate accusamus ut et recusandae. Rerum ex repellendus assumenda et. Ab reiciendis quia perspiciatis deserunt ducimus corrupti.",
"med_info_optin": false,
"share_true_info_optin": false,
"dashboard_url": "https://cronin.com/incidunt-iure-odit-et-et-modi-ipsum.html",
"report_details": "Caso de Desconhecido. Relato e B.O. em: https://cronin.com/incidunt-iure-odit-et-et-modi-ipsum.html.",
"qualification_errors": [],
"ispb_data": {
"id": 167,
"name": "Leuschke-Feeney Bank",
"compe": "227",
"ispb": "04415490",
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
"reporter": {
"id": 78,
"bank_id": 168,
"document": "7059720839",
"document_type": "cpf",
"name": "Schultz Group",
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
"counterparty": {
"id": 79,
"bank_id": 170,
"document": "0261536693",
"document_type": "cnpj",
"name": "Fahey, Cartwright and Balistreri",
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
{
"id": 50,
"transaction_id": "E2E2213199",
"transaction_amount": "5814.67",
"transaction_time": "2025-07-11T18:20:53.000000Z",
"transaction_description": "Rem est esse sint aut.",
"reporter_client_name": "Bernhard, Tromp and Baumbach",
"reporter_client_id": "4159682090",
"contested_participant_id": null,
"counterparty_client_name": "Marquardt-Klocko",
"counterparty_client_id": "8764418754",
"counterparty_client_key": "8c352249-2535-3e45-8de4-d6620458a778",
"protocol_id": "efb45134-b05b-36f6-b20a-f93610c7e46f",
"pix_auto": null,
"ispb": "41312753",
"client_id": null,
"client_since": "2025-07-21T18:20:53.000000Z",
"client_birth": null,
"autofraud_risk": null,
"latest_status": "requested",
"latest_refund_status": "pending",
"latest_refund_status_reason": null,
"situation_type": null,
"report_merge": false,
"category": "coercion",
"sub_category": "other_commercial-dispute-buy",
"tactic": "scam_get-item_money",
"scam_checks": [
"scam-check_delay-site-down"
],
"channels": [
"scammer_youtube"
],
"items": [
"item_phone-accessory",
"item_hire-other",
"item_developer"
],
"origin_channel": "scammer_landline",
"is_over_60_optin": true,
"report": "Eaque neque sit sunt. Accusantium odit ut perspiciatis. Dolorem aut quis ut dolores omnis. Earum consequatur asperiores est vel id aut officiis eos.",
"med_info_optin": false,
"share_true_info_optin": false,
"dashboard_url": "http://www.robel.com/corporis-nesciunt-ut-ratione-iure-impedit-molestiae",
"report_details": "Caso de Desconhecido. Relato e B.O. em: http://www.robel.com/corporis-nesciunt-ut-ratione-iure-impedit-molestiae.",
"qualification_errors": [],
"ispb_data": {
"id": 171,
"name": "Bauch Group Bank",
"compe": "045",
"ispb": "41312753",
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
"reporter": {
"id": 80,
"bank_id": 172,
"document": "4159682090",
"document_type": "cpf",
"name": "Bernhard, Tromp and Baumbach",
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
"counterparty": {
"id": 81,
"bank_id": 174,
"document": "8764418754",
"document_type": "cpf",
"name": "Marquardt-Klocko",
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
}
],
"links": {
"first": "/?page=1",
"last": null,
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"path": "/",
"per_page": "15",
"to": 2
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create a new MED request.
requires authentication
Example request:
curl --request POST \
"http://localhost/api/v1/med-requests" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"transaction_id\": \"architecto\",
\"transaction_amount\": 22,
\"transaction_time\": \"2051-05-26\",
\"transaction_description\": \"architecto\",
\"reporter_client_name\": \"architecto\",
\"reporter_client_id\": 4326.41688,
\"contested_participant_id\": \"architecto\",
\"counterparty_client_name\": \"architecto\",
\"counterparty_client_id\": 4326.41688,
\"counterparty_client_key\": \"architecto\",
\"protocol_id\": \"architecto\",
\"pix_auto\": true,
\"ispb\": 4326.41688,
\"client_id\": \"architecto\",
\"client_since\": \"2025-07-21\",
\"client_birth\": \"2025-07-21\",
\"autofraud_risk\": false
}"
const url = new URL(
"http://localhost/api/v1/med-requests"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"transaction_id": "architecto",
"transaction_amount": 22,
"transaction_time": "2051-05-26",
"transaction_description": "architecto",
"reporter_client_name": "architecto",
"reporter_client_id": 4326.41688,
"contested_participant_id": "architecto",
"counterparty_client_name": "architecto",
"counterparty_client_id": 4326.41688,
"counterparty_client_key": "architecto",
"protocol_id": "architecto",
"pix_auto": true,
"ispb": 4326.41688,
"client_id": "architecto",
"client_since": "2025-07-21",
"client_birth": "2025-07-21",
"autofraud_risk": false
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"data": {
"url": null
}
}
Example response (422):
{
"message": "The given data was invalid.",
"errors": {
"transaction_id": [
"required",
"not-a-string"
],
"transaction_amount": [
"required",
"not-a-number",
"value-too-low"
],
"transaction_time": [
"required",
"not-a-date",
"wrong-date-format",
"too-old"
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
errors
object
*
string[]
List of possible error slugs: required, not-a-string, not-a-number, value-too-low, not-a-date, wrong-date-format, too-old, wrong-format, invalid-value
Display a specific MED request.
requires authentication
Example request:
curl --request GET \
--get "http://localhost/api/v1/med-requests/20?load[]=scamReport&load[]=taxonomy" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"load\": [
\"architecto\"
]
}"
const url = new URL(
"http://localhost/api/v1/med-requests/20"
);
const params = {
"load[0]": "scamReport",
"load[1]": "taxonomy",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"load": [
"architecto"
]
};
fetch(url, {
method: "GET",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"data": {
"id": 51,
"transaction_id": "E2E5449171",
"transaction_amount": "2449.73",
"transaction_time": "2025-07-11T18:20:53.000000Z",
"transaction_description": "Deserunt aut ab provident perspiciatis quo omnis nostrum.",
"reporter_client_name": "Leuschke, Bauch and Fritsch",
"reporter_client_id": "0951073658",
"contested_participant_id": null,
"counterparty_client_name": "Raynor Ltd",
"counterparty_client_id": "9444597233",
"counterparty_client_key": "bfc53181-d647-36b2-9080-f9c2b76006f4",
"protocol_id": "5d093e7f-5aae-3aa3-bece-f6e784dcbd67",
"pix_auto": null,
"ispb": "21988862",
"client_id": null,
"client_since": "2025-07-21T18:20:53.000000Z",
"client_birth": null,
"autofraud_risk": null,
"latest_status": "requested",
"latest_refund_status": "pending",
"latest_refund_status_reason": null,
"situation_type": null,
"report_merge": false,
"category": "other",
"sub_category": "fraudulent_access_known-person",
"tactic": "scam_get-money_damages-compensation",
"scam_checks": [
"scam-check_delivered-false-item"
],
"channels": [
"phone-unknown",
"discord"
],
"items": [
"item_health-service"
],
"origin_channel": "call-known",
"is_over_60_optin": false,
"report": "Dignissimos neque blanditiis odio. Excepturi doloribus delectus fugit qui repudiandae laboriosam. Alias tenetur ratione nemo voluptate accusamus ut et. Modi rerum ex repellendus assumenda et tenetur.",
"med_info_optin": false,
"share_true_info_optin": false,
"dashboard_url": "http://www.okuneva.com/fugiat-sunt-nihil-accusantium-harum-mollitia.html",
"report_details": "Caso de Desconhecido. Relato e B.O. em: http://www.okuneva.com/fugiat-sunt-nihil-accusantium-harum-mollitia.html.",
"qualification_errors": [],
"ispb_data": {
"id": 175,
"name": "Hauck-Leuschke Bank",
"compe": "279",
"ispb": "21988862",
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
"reporter": {
"id": 82,
"bank_id": 176,
"document": "0951073658",
"document_type": "cpf",
"name": "Leuschke, Bauch and Fritsch",
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
"counterparty": {
"id": 83,
"bank_id": 178,
"document": "9444597233",
"document_type": "cnpj",
"name": "Raynor Ltd",
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update a MED request.
requires authentication
Example request:
curl --request PUT \
"http://localhost/api/v1/med-requests/20" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"latest_status\": \"acknowledged\",
\"latest_status_reason\": \"commercial-disagreement\",
\"latest_refund_status\": \"rejected\",
\"latest_refund_status_reason\": \"account-closure\",
\"situation_type\": \"ACCOUNT_TAKEOVER\",
\"category\": \"coercion\",
\"sub_category\": \"scam_get-profit\",
\"tactic\": \"scam_debt-charge_utilities\",
\"scam_checks\": [
\"scam-check_delivered-none\"
],
\"channels\": [
{
\"scammer_email\": \"email@provider.com\"
},
{
\"scammer_phone\": \"5511987654433\"
}
],
\"origin_channel\": \"facebook-msg-known-hacked\",
\"med_info_optin\": false,
\"share_true_info_optin\": false,
\"is_over_60_optin\": false,
\"report\": \"architecto\",
\"items\": [
\"item_health-service\"
],
\"dashboard_url\": \"http:\\/\\/bailey.com\\/\"
}"
const url = new URL(
"http://localhost/api/v1/med-requests/20"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"latest_status": "acknowledged",
"latest_status_reason": "commercial-disagreement",
"latest_refund_status": "rejected",
"latest_refund_status_reason": "account-closure",
"situation_type": "ACCOUNT_TAKEOVER",
"category": "coercion",
"sub_category": "scam_get-profit",
"tactic": "scam_debt-charge_utilities",
"scam_checks": [
"scam-check_delivered-none"
],
"channels": [
{
"scammer_email": "email@provider.com"
},
{
"scammer_phone": "5511987654433"
}
],
"origin_channel": "facebook-msg-known-hacked",
"med_info_optin": false,
"share_true_info_optin": false,
"is_over_60_optin": false,
"report": "architecto",
"items": [
"item_health-service"
],
"dashboard_url": "http:\/\/bailey.com\/"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"data": {
"id": 52,
"transaction_id": "E2E9026316",
"transaction_amount": "2250.00",
"transaction_time": "2025-07-11T18:20:53.000000Z",
"transaction_description": "Perspiciatis quo omnis nostrum aut adipisci quidem nostrum qui.",
"reporter_client_name": "McLaughlin and Sons",
"reporter_client_id": "5671733515",
"contested_participant_id": null,
"counterparty_client_name": "Wisoky-Kshlerin",
"counterparty_client_id": "3608007829",
"counterparty_client_key": "0a9446d3-4070-3757-8926-67a9d2adbc0e",
"protocol_id": "c68e0767-6220-31fb-a489-61093ff79529",
"pix_auto": null,
"ispb": "95107365",
"client_id": null,
"client_since": "2025-07-21T18:20:53.000000Z",
"client_birth": null,
"autofraud_risk": null,
"latest_status": "requested",
"latest_refund_status": "pending",
"latest_refund_status_reason": null,
"situation_type": null,
"report_merge": false,
"category": "operational_flaw",
"sub_category": "scam_job",
"tactic": "scam_get-item_donation",
"scam_checks": [
"scam-check_delivered-heavy-item"
],
"channels": [
"app-travel",
"search-engine"
],
"items": [
"item_computer"
],
"origin_channel": "app-job",
"is_over_60_optin": false,
"report": "Veritatis excepturi doloribus delectus fugit. Repudiandae laboriosam est alias tenetur ratione. Voluptate accusamus ut et recusandae. Rerum ex repellendus assumenda et.",
"med_info_optin": false,
"share_true_info_optin": false,
"dashboard_url": "http://www.okon.com/accusantium-harum-mollitia-modi-deserunt-aut-ab",
"report_details": "Caso de Desconhecido. Relato e B.O. em: http://www.okon.com/accusantium-harum-mollitia-modi-deserunt-aut-ab.",
"qualification_errors": [],
"ispb_data": {
"id": 179,
"name": "Leuschke, Bauch and Fritsch Bank",
"compe": "058",
"ispb": "95107365",
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
"reporter": {
"id": 84,
"bank_id": 180,
"document": "5671733515",
"document_type": "cpf",
"name": "McLaughlin and Sons",
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
"counterparty": {
"id": 85,
"bank_id": 182,
"document": "3608007829",
"document_type": "cnpj",
"name": "Wisoky-Kshlerin",
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Notification Content Management
APIs for managing notification content for webhook events
Remove the specified notification content.
requires authentication
Example request:
curl --request DELETE \
"http://localhost/api/v1/notification-contents/16" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost/api/v1/notification-contents/16"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Example response (204):
Empty response
Example response (404):
{
"message": "Notification content not found."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Taxonomy management
APIs for managing taxonomy categories
List taxonomy categories.
requires authentication
Example request:
curl --request GET \
--get "http://localhost/api/v1/taxonomy/categories?filters=%7B%22slug%22%3A+%22category-slug%22%7D&per_page=15&page=1" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost/api/v1/taxonomy/categories"
);
const params = {
"filters": "{"slug": "category-slug"}",
"per_page": "15",
"page": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": 39,
"slug": "adipisci-quidem-nostrum",
"name": "qui commodi incidunt",
"order": 63,
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
{
"id": 40,
"slug": "et-et",
"name": "modi ipsum nostrum",
"order": 59,
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List taxonomy subcategories.
requires authentication
Example request:
curl --request GET \
--get "http://localhost/api/v1/taxonomy/subcategories?filters=%7B%22slug%22%3A+%22subcategory-slug%22%7D&per_page=15&page=1" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost/api/v1/taxonomy/subcategories"
);
const params = {
"filters": "{"slug": "subcategory-slug"}",
"per_page": "15",
"page": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": 58,
"taxonomy_category_id": 41,
"slug": "commodi-incidunt",
"name": "iure odit et",
"order": 45,
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
{
"id": 59,
"taxonomy_category_id": 42,
"slug": "enim-non-facere",
"name": "tempora ex voluptatem",
"order": 28,
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List taxonomy channels.
requires authentication
Example request:
curl --request GET \
--get "http://localhost/api/v1/taxonomy/channels?filters=%7B%22slug%22%3A+%22channel-slug%22%7D&per_page=15&page=1" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost/api/v1/taxonomy/channels"
);
const params = {
"filters": "{"slug": "channel-slug"}",
"per_page": "15",
"page": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": 51,
"slug": "odit-et",
"name": "et modi ipsum",
"order": 66,
"group_slug": "autem-et-consequatur",
"group_name": "aut dolores",
"type_slug": "non-facere",
"type_name": "tempora",
"owner_slug": "voluptatem-laboriosam",
"owner_name": "Schultz Group",
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
{
"id": 52,
"slug": "fugit-deleniti-distinctio",
"name": "eum doloremque id",
"order": 89,
"group_slug": "aliquam-veniam-corporis",
"group_name": "dolorem mollitia",
"type_slug": "nemo",
"type_name": "odit",
"owner_slug": "officia-est-dignissimos",
"owner_name": "Ward-O'Connell",
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List taxonomy items.
requires authentication
Example request:
curl --request GET \
--get "http://localhost/api/v1/taxonomy/items?filters=%7B%22slug%22%3A+%22item-slug%22%7D&per_page=15&page=1" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost/api/v1/taxonomy/items"
);
const params = {
"filters": "{"slug": "item-slug"}",
"per_page": "15",
"page": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": 57,
"slug": "modi-ipsum",
"name": "nostrum omnis autem",
"type": "buy",
"order": 68,
"is_physical_item": false,
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
{
"id": 58,
"slug": "ex-voluptatem",
"name": "laboriosam praesentium quis",
"type": "hire",
"order": 84,
"is_physical_item": true,
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List taxonomy scam checks.
requires authentication
Example request:
curl --request GET \
--get "http://localhost/api/v1/taxonomy/scam-checks?filters=%7B%22slug%22%3A+%22scam-check-slug%22%7D&per_page=15&page=1" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost/api/v1/taxonomy/scam-checks"
);
const params = {
"filters": "{"slug": "scam-check-slug"}",
"per_page": "15",
"page": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": 32,
"slug": "omnis-autem",
"name": "et consequatur aut",
"type": "hire",
"order": 33,
"level": 2,
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
{
"id": 33,
"slug": "tempora-ex",
"name": "voluptatem laboriosam praesentium",
"type": "hire",
"order": 24,
"level": 4,
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List taxonomy tactics.
requires authentication
Example request:
curl --request GET \
--get "http://localhost/api/v1/taxonomy/tactics?filters=%7B%22slug%22%3A+%22tactic-slug%22%7D&per_page=15&page=1" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"http://localhost/api/v1/taxonomy/tactics"
);
const params = {
"filters": "{"slug": "tactic-slug"}",
"per_page": "15",
"page": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": 102,
"taxonomy_subcategory_id": 60,
"slug": "consequatur-aut-dolores",
"name": "enim non facere",
"order": 25,
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
},
{
"id": 103,
"taxonomy_subcategory_id": 61,
"slug": "aliquam-veniam-corporis",
"name": "dolorem mollitia deleniti",
"order": 37,
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Generate taxonomy.
requires authentication
Example request:
curl --request POST \
"http://localhost/api/v1/taxonomy/generate" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"report\": \"architecto\"
}"
const url = new URL(
"http://localhost/api/v1/taxonomy/generate"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"report": "architecto"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"sub_category": "fraudulent_access",
"tactic": "fraudulent_access_fake_bank_site",
"channels": [
"scam_bank_alert_unknown_pix"
],
"items": [
"scam_bank_alert_unknown_pix"
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Webhook Subscription Management
APIs for managing webhook subscriptions
Register a new webhook subscription.
requires authentication
Example request:
curl --request POST \
"http://localhost/api/v1/webhook-subscriptions" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"url\": \"https:\\/\\/example.com\\/webhook\",
\"event_type\": \"med-request.created\",
\"actor_id\": 1,
\"actor_type\": \"origin-bank\"
}"
const url = new URL(
"http://localhost/api/v1/webhook-subscriptions"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"url": "https:\/\/example.com\/webhook",
"event_type": "med-request.created",
"actor_id": 1,
"actor_type": "origin-bank"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"data": {
"id": 18,
"actor_id": null,
"actor_type": "first-party-app",
"event_type": "INFRACTION:ACKNOWLEDGED",
"url": "http://www.okon.com/accusantium-harum-mollitia-modi-deserunt-aut-ab",
"created_at": "2025-07-21T18:20:53.000000Z",
"updated_at": "2025-07-21T18:20:53.000000Z",
"secret_key": null
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Webhook Notifications
Overview
Webhook notifications are sent to clients when specific events occur in the system. These notifications are triggered based on the webhook subscriptions registered by the clients. Each notification contains an event payload and is signed with a secret key to ensure its authenticity.
Notification Structure
Webhook notifications are sent as HTTP POST requests to the URL specified in the webhook subscription. The request contains the following:
Headers
Content-Type:application/jsonX-CAM-Signature: A HMAC-SHA256 signature of the payload, generated using the secret key provided during subscription registration.
Body
The body of the request is a JSON object with the following structure:
{
"event_type": "string", // The type of event (e.g., med-request.created, med-request.updated)
"med_request_id": "integer", // The ID of the MED request related to the event
"timestamp": "string" // ISO 8601 timestamp of the event
}
Validating the Signature
To ensure the authenticity of the webhook notification, clients must validate the X-CAM-Signature header. Follow these steps to validate the signature:
- Retrieve the
X-CAM-Signatureheader from the request. - Compute the HMAC-SHA256 hash of the request payload using the secret key provided during subscription registration.
- Compare the computed hash with the value of the
X-CAM-Signatureheader. If they match, the notification is authentic.
Note on Secret Key Hashing
When validating the signature, clients must first hash their plain secret key using a SHA-256 hash algorithm (for example hash('sha256', $plainSecretKey) in PHP) before computing the HMAC-SHA256 hash of the payload.
Updated Example Validation Code
Below is an updated example of how to validate the signature in PHP, considering the secret key hashing:
$payload = file_get_contents('php://input');
$receivedSignature = $_SERVER['HTTP_X_CAM_SIGNATURE'];
$plainSecretKey = 'your-plain-secret-key'; // Replace with your actual plain secret key
// Hash the plain secret key
$hashedSecretKey = hash('sha256', $plainSecretKey);
// Compute the HMAC-SHA256 hash of the payload
$computedSignature = hash_hmac('sha256', $payload, $hashedSecretKey);
if (hash_equals($computedSignature, $receivedSignature)) {
// Signature is valid
http_response_code(200);
echo 'Notification received and verified.';
} else {
// Signature is invalid
http_response_code(403);
echo 'Invalid signature.';
}
Handling Notifications
Clients should respond to webhook notifications with an HTTP status code:
200 OK: Indicates that the notification was received and processed successfully.- Any other status code: Indicates that the notification was not processed successfully. The system may retry sending the notification based on its retry policy.
Retry Policy
If a webhook notification fails (e.g., due to a network error or an invalid response code), the system will retry sending the notification. The retry policy includes exponential backoff and a maximum number of retries.
Security Best Practices
- Use HTTPS for your webhook endpoint to ensure data is transmitted securely.
- Keep your secret key confidential and rotate it periodically.
- Validate the
X-CAM-Signatureheader for every notification to ensure authenticity. - Log received notifications and their processing status for auditing and debugging purposes.
MED Request Status Webhook System
This webhook allows for automated retrieval of MedRequest status updates from external sources via webhooks.
The event type for refund status updates is fetch.med-request-refund-status.
Expected Response Format
Your webhook endpoint should return a JSON array of objects with the following structure:
[
{
"med_request_id": 1234,
"status": "accepted",
"refund_status": "refunded"
},
{
"med_request_id": 5678,
"status": "rejected",
"refund_status": "med-denied"
}
]
Valid status values are:
requestedin-reviewopenedacceptedrejectedclosedcancelled
Valid refund status values are:
pendingrefundednot-refundedpartial-refundedmed-openedmed-deniedno-fundsnot-refunded/scamdeniedno-infractioninfraction-received