Receives a Reserve Funding Request from the external reserve funding service. Validates the payload (the merchant MID is resolved against HQ), enforces idempotency on externalRequestId (duplicate returns HTTP 200 with duplicate=true), downloads and stores the signed document internally, and saves the request with Pending status for review in the Reserve Funding Requests module. The reserve department backing the request is chosen by HQ from the merchant's own bank; the caller neither sends nor needs a departmentId, and fundingDepartment carries only departmentName, which is informational. Returns HTTP 201 with the internal requestId; validation errors are returned together as HTTP 400 (errors). Requires the "Allow Reserve Funding API access" role option (otherwise HTTP 403); missing or invalid credentials return HTTP 401.

Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…

Submit a Reserve Funding Request

POST /api/v1/reserve-funding/requests

Submits a signed reserve funding agreement to Netevia HQ for review. The agreement itself is negotiated outside HQ — the external service sets the terms and the merchant signs the document — so this call is where that already-signed request enters the system. HQ does not obtain consent; it validates the data, stores the signed document, and creates a Pending request in the Reserve Funding Requests review queue for a Netevia employee to Approve or Reject.

This is the first of two related endpoints. Use GET /api/v1/reserve-funding/requests/{externalRequestId} to read back the decision — it is the authoritative status, complementing the best-effort decision callback.

Authentication

Basic HTTP authentication. The API user must have the Reserve Funding API access permission (referred to internally as the "allow Reserve Funding Management API" role option) and the manage-reserve-funding-requests module enabled. Without either, the call fails with 403.

Request body

{
  "externalRequestId": "RF-2026-09-0001",
  "merchant": {
    "mid": "9180465590107730",
    "dbaName": "The Best Tires"
  },
  "fundingDepartment": {
    "departmentId": "STG824-RSV-9180",
    "departmentName": "Reserve API Approval"
  },
  "fundingTerms": {
    "startDate": "2026-09-15",
    "stopDate": "2026-12-31",
    "percent": 11,
    "ceiling": 25000
  },
  "document": {
    "fileName": "Reserve-Agreement-The-Best-Tires.pdf",
    "fileType": "pdf",
    "fileUrl": "https://files.example.com/agreements/best-tires.pdf"
  },
  "email": "[email protected]"
}

Fields

Validation is exhaustive — every failing rule is returned together in one response, so you never fix one error only to discover another on the next attempt.

FieldTypeRequiredNotes
externalRequestIdstringRequiredYour own identifier for the request. Echoed on every response and used as the path parameter when reading the decision back. Trimmed before storage/comparison; max 64 characters. This is the idempotency key — see below. Uniqueness is scoped to your API user, so another integrator can reuse the same string without colliding with you.
merchant.midstringRequiredThe merchant's MID at Netevia, resolved at submit time. If approved, this is the merchant the reserve is created on. Max 32 characters. The lookup is exact and not trimmed — a stray leading/trailing space fails it with merchant not found.
merchant.dbaNamestringRequiredTrading name, stored on the request and shown to the reviewer. Max 128 characters. Not checked against the merchant record — whatever you send is what the reviewer sees, so a mismatch slows the review down rather than failing the call.
fundingDepartment.departmentIdstringRequiredSelects the reserve department — the account and routing number the withheld funds are held against. Netevia provisions these and supplies the id. Max 64 characters. Must match a live department (department not found otherwise) and must be a Reserve department, indicator 2 — a Risk department (indicator 1) is refused with Risk departments are not accepted. The department's bank must also match the merchant's bank, but that is not checked at submit time; a mismatch surfaces later as a failed processingResult after approval.
fundingDepartment.departmentNamestringRequiredFree text stored alongside the request and shown in the review queue. Max 128 characters. Not matched against the department record — departmentId is what actually selects the department.
fundingTerms.startDatedateRequiredDate the reserve begins accruing. ISO date or date-time.
fundingTerms.stopDatedateOptionalDate the reserve stops. Omit entirely for an open-ended reserve. Must be on or after startDate, else fundingTerms.stopDate must be on or after fundingTerms.startDate.
fundingTerms.percentnumberOne of percent/amount requiredPercentage of each settlement withheld, as a number, not a fraction — 10 means 10%. Greater than 0, at most 100. Rounded to 4 decimal places (away from zero) before validation, so a value under 0.00005 is rejected rather than silently stored as zero.
fundingTerms.amountnumberOne of percent/amount requiredFixed amount withheld per settlement, instead of or in addition to percent. Send both and both rules apply. Greater than 0, at most 9,999,999.99 (the widest value the fixed-width TSYS record can carry). Same 4-decimal rounding as percent. At least one of percent/amount is required, else At least one of fundingTerms.percent or fundingTerms.amount is required., reported against the fundingTerms field.
fundingTerms.ceilingnumberRequiredTotal at which the reserve stops accruing, regardless of whether you used percent, amount, or both. Greater than 0, at most 9,999,999.99. Same 4-decimal rounding.
document.fileUrlstringRequiredWhere Netevia fetches the signed agreement from. The download happens synchronously inside this call — an unreachable URL fails the request rather than failing later in review. Must be reachable from Netevia's servers without a login; a URL that only resolves inside your own network will fail with Document could not be retrieved from the provided URL.
document.fileNamestringRequiredThe name given to the stored file, and the link text the reviewer clicks. Independent of the URL — you can serve a1b2c3.pdf from fileUrl and have it stored under this name. Max 256 characters; must not contain " < > | : * ? / \. The extension, not fileType, decides the stored type and must be pdf, jpg, jpeg, or png — a .docx name is refused even when fileType says pdf.
document.fileTypestringRequiredDeclared file type: one of pdf, jpg, png (jpeg accepted as an alias for jpg). Trimmed and case-insensitive. Anything else → document.fileType must be one of: pdf, jpg, png.
document.fileAccessTokenstringOptionalSent as Authorization: Bearer … with the download, when your file store requires one. Omit for a plain public URL.
emailstringRequiredContact address stored on the request and displayed in the review queue. Max 256 characters. Not validated as an email format, and no mail is ever sent to it — it is a display field for the reviewer, not a notification channel.

Responses

200 — Created

{
  "data": {
    "requestId": "HQ-RF-REQ-101",
    "externalRequestId": "RF-2026-09-0001",
    "status": "Pending",
    "duplicate": false
  },
  "requestId": 407166,
  "success": true
}

A successful submission answers 200, not 201 — this is the general Netevia HQ platform convention for creation calls. data.requestId is the internal HQ-RF-REQ-<n> reference, identical to the one the GET endpoint and the decision callback will use.

200 — Duplicate (idempotent replay, nothing created)

{
  "data": {
    "requestId": "HQ-RF-REQ-101",
    "externalRequestId": "RF-2026-09-0001",
    "status": "Approved",
    "duplicate": true
  },
  "requestId": 407170,
  "success": true
}

Re-submitting an externalRequestId you've already used returns the original request with duplicate: true — and that request's current status, which may already be Approved or Rejected. This is a safe retry, not an error: it is the intended way to recover from a timeout or a network failure on your side, so treat duplicate: true as "already submitted, go read the status" rather than as a failure.

400 — Validation failed (nothing created)

{
  "requestId": 407184,
  "success": false,
  "validationErrors": [
    { "field": "document.fileType", "error": "document.fileType must be one of: pdf, jpg, png." },
    { "field": "merchant.mid",       "error": "merchant not found" },
    { "field": "fundingTerms",       "error": "At least one of fundingTerms.percent or fundingTerms.amount is required." }
  ]
}

The message key is error, not message. field uses dotted paths matching the request body, except for cross-field rules (such as the percent/amount check above), which are reported against their parent object.

403 — Forbidden

Returned when the authenticated API user is missing the manage-reserve-funding-requests module or the "allow Reserve Funding Management API" role option.

Notes

  • Idempotency: externalRequestId is the dedup key, scoped per API user. Retrying a POST after a timeout is always safe.
  • Synchronous document fetch: the signed document is downloaded during this call, not asynchronously afterward — a slow or unreachable file URL will fail the submission itself.
  • This call never returns a decision. It only ever creates a Pending request (or reports a duplicate of one already submitted). The decision comes later, via the GET endpoint or the callback.

OpenAPI definition

{
  "openapi": "3.0.0",
  "info": {
    "version": "v1",
    "title": "Netevia HQ | API Documentation",
    "description": "Netevia HQ | API Documentation"
  },
  "paths": {
    "/api/v1/reserve-funding/requests": {
      "post": {
        "tags": ["ReserveFundingApi"],
        "summary": "Submit a Reserve Funding Request",
        "operationId": "ReserveFundingApi_SubmitReserveFundingRequest",
        "requestBody": {
          "content": {
            "application/json": { "schema": { "$ref": "#/components/schemas/ReserveFundingApiRequest" } },
            "text/json": { "schema": { "$ref": "#/components/schemas/ReserveFundingApiRequest" } },
            "application/xml": { "schema": { "$ref": "#/components/schemas/ReserveFundingApiRequest" } },
            "text/xml": { "schema": { "$ref": "#/components/schemas/ReserveFundingApiRequest" } },
            "application/x-www-form-urlencoded": { "schema": { "$ref": "#/components/schemas/ReserveFundingApiRequest" } }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": { "schema": { "type": "object" } },
              "text/json": { "schema": { "type": "object" } },
              "application/xml": { "schema": { "type": "object" } },
              "text/xml": { "schema": { "type": "object" } }
            }
          }
        }
      }
    }
  },
  "security": [{ "Basic": [] }],
  "servers": [{ "url": "https://hq.staging.netevia.dev" }],
  "components": {
    "securitySchemes": {
      "Basic": { "type": "http", "description": "Basic HTTP Authentication", "scheme": "basic" }
    },
    "schemas": {
      "ReserveFundingApiRequest": {
        "type": "object",
        "properties": {
          "externalRequestId": { "type": "string" },
          "merchant": { "$ref": "#/components/schemas/ReserveFundingApiMerchant" },
          "fundingDepartment": { "$ref": "#/components/schemas/ReserveFundingApiDepartment" },
          "fundingTerms": { "$ref": "#/components/schemas/ReserveFundingApiTerms" },
          "document": { "$ref": "#/components/schemas/ReserveFundingApiDocument" },
          "email": { "type": "string" }
        }
      },
      "ReserveFundingApiMerchant": {
        "type": "object",
        "properties": { "mid": { "type": "string" }, "dbaName": { "type": "string" } }
      },
      "ReserveFundingApiDepartment": {
        "type": "object",
        "properties": { "departmentId": { "type": "string" }, "departmentName": { "type": "string" } }
      },
      "ReserveFundingApiTerms": {
        "type": "object",
        "properties": {
          "startDate": { "format": "date-time", "type": "string" },
          "stopDate": { "format": "date-time", "type": "string" },
          "percent": { "format": "double", "type": "number" },
          "amount": { "format": "double", "type": "number" },
          "ceiling": { "format": "double", "type": "number" }
        }
      },
      "ReserveFundingApiDocument": {
        "type": "object",
        "properties": {
          "fileName": { "type": "string" },
          "fileType": { "type": "string" },
          "fileUrl": { "type": "string" },
          "fileAccessToken": { "type": "string" }
        }
      }
    }
  }
}
Body Params
string
merchant
object
fundingDepartment
object
fundingTerms
object
document
object
string
Headers
string
enum
Defaults to application/json

Generated from available response content types

Allowed:
string
enum
Defaults to application/json

Generated from available request content types

Allowed:
Response

Language
Credentials
Basic
base64
:
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json
text/json