FactorView API Documentation

FactorView's REST API allows you to read and write data within your FactorView account.

IMPORTANT: Do not provide your API key + session token to anyone, as it grants full access to your FactorView data.

Authentication

In order to generate your session token, a request must be sent containing your API key as a header with the name "X-API-KEY".
Session tokens are valid for up to 15 minutes. Your unique "<URL>" will be provided with your API key.

	curl -H "X-API-KEY: YOUR_API_KEY_HERE" /
	"<URL>/api/v1/auth"

Email support@factorview.com to request your API key and unique URL.

Request Structure

<url>/api/v1/<endpoint>/<identifier>/<arguments>

Each request must contain the API key + session token passed within the header as "X-API-KEY" and "X-API-SECRET".
Your unique "<URL>" will be provided with your API key.

For example,

	curl -H "X-API-KEY: YOUR_API_KEY_HERE" /
	-H "X-API-SECRET: YOUR_API_SESSION_TOKEN_HERE" /
	"<URL>/api/v1/invoice/123456"

Company

GET /company

Return a list of companies (clients and/or debtors)

Optional URL params:

  • type : client or debtor
  • mc_number : find companies matching, by MC Number (if transportation)
  • dot_number : find companies matching, by DOT Number (if transportation)
  • min_date=YYYY-MM-DD : results greater than the date specified, by created_date
  • max_date=YYYY-MM-DD : results less than the date specified, by created_date
  • last_modified=YYYY-MM-DD : results greater than the date specified, by last_modified
  • per_page : number of results to return per page (default is 100)
  • page : which page of results to return based on per_page (default is 1)

Response example:

{
	"companies": [
		{
			"company_id": "1001",
			"type": "Client",
			"created_date": "2025-01-18",
			"name": "ABC Company Inc",
			"dba_name": "ABC Freight",
			"personal_name": "John Smith",
			"created_by": "SYSTEM",
			"address1": "1234 Somestreet 412",
			"address2": "",
			"city": "San Antonio",
			"state": "TX",
			"zip": "78258",
			"country": "",
			"phone": "555-555-5555",
			"mobile": "555-555-5556",
			"fax": "",
			"email": "email@yahoo.com",
			"email2": "secondary@yahoo.com",
			"email_noa": "noa@yahoo.com",
			"email_billing": "ar@yahoo.com",
			"email_pay_status": "ap@yahoo.com",
			"account_rep": {
				"id": "12",
				"name": "Bob Smith"
			},
			"sales_rep": {
				"id": "21",
				"name": "Jamie Jones"
			},
			"buy_limit": "40000.00",
			"buy_notes": "Special buy notes show up here",
			"risk_score": "85",
			"restricted": "N",
			"is_active": "1",
			"preferred_pay_type": "ACH -$2.50",   // "" if not set
			"preferred_bank": {                   // [] if not set
				"code": "operating-1",
				"name": "Operating Account"
			},
			"preferred_contact_method": "email",  // "" if not set
			"tin": "12-3456789",
			"industry": "Trucking",
			"warning_status": "Warning status here.",   // free text, may be long or empty
			"discount_pct": "0.035000",   // decimal fraction, not a percentage: 0.035000 = 3.5%
			"escrow_pct": "0.100000",     // decimal fraction, not a percentage: 0.100000 = 10%
			"last_modified": "2025-12-19 10:09:30",
			"mc_number": "123456"   // if transportation
		},
		{
			... : ...
		}
	],
	"page": 2,
	"per_page": 25, 
	"count": 17
}

GET /company/:id

Return a single company (client or debtor) by specific company ID

Response example: /company/1001

{
	"company_id": "1001",
	"type": "Client",
	"created_date": "2025-01-18",
	"name": "ABC Company Inc",
	"dba_name": "ABC Freight",
	"personal_name": "John Smith",
	"created_by": "SYSTEM",
	"address1": "1234 Somestreet 412",
	"address2": "",
	"city": "San Antonio",
	"state": "TX",
	"zip": "78258",
	"country": "",
	"phone": "555-555-5555",
	"mobile": "555-555-5556",
	"fax": "",
	"email": "email@yahoo.com",
	"email2": "secondary@yahoo.com",
	"email_noa": "noa@yahoo.com",
	"email_billing": "ar@yahoo.com",
	"email_pay_status": "ap@yahoo.com",
	"account_rep": {
		"id": "12",
		"name": "Bob Smith"
	},
	"sales_rep": {
		"id": "21",
		"name": "Jamie Jones"
	},
	"buy_limit": "40000.00",
	"buy_notes": "Special buy notes show up here",
	"risk_score": "85",
	"restricted": "N",
	"is_active": "1",
	"preferred_pay_type": "ACH -$2.50",   // "" if not set
	"preferred_bank": {                   // [] if not set
		"code": "operating-1",
		"name": "Operating Account"
	},
	"preferred_contact_method": "email",  // "" if not set
	"tin": "12-3456789",
	"industry": "Trucking",
	"warning_status": "Warning status here.",   // free text, may be long or empty
	"discount_pct": "0.035000",   // decimal fraction, not a percentage: 0.035000 = 3.5%
	"escrow_pct": "0.100000",     // decimal fraction, not a percentage: 0.100000 = 10%
	"last_modified": "2025-12-19 10:09:30",
	"mc_number": "123456"   // if transportation
}

POST /company

Create a company (client or debtor)

Required fields: type, name, active, address1, city, state, zip, country, phone, email, buylimit

Request body example:

{
	"type": "client",  // as 'client' or 'debtor'
	"name": "New Client Company Name",
	"address1": "",
	"address2": "",
	"city": "",
	"state": "",
	"zip": "",
	"country": "",
	"phone": "",
	"mobile": "",
	"email": "",
	"buylimit": "0.00",
	"buynotes": "", 
	"images":[
		{
			"url":"https://linkurl/3823k20a23.pdf",
			"image_name":"Setup document"
			
		},{
			"url":"https://linkurl/27iwh6273a.pdf",
			"image_name":"Due diligence"
			
		}
	]
}

Response example: (Company ID)

	"12345"

PUT /company/:id

Update a single company (client or debtor) by ID

Available fields: name, dba_name, personal_name, address1, address2, city, state, zip, country, phone, email, buy_limit, buy_notes, risk_score, warning_status, restricted, active, images (if transportation: mc_number, dot_number).

Fields and values must be in a proper URL-encoded query string.

Request example:

	/company/12345/?name=New+Company+Name&address1=123+New+Street

Response example:

	1



Company Link (NOA Status)

Read and update the client/debtor link relationship, including its NOA status (noa_status) and note. The link is identified by the client ID (in the URL) and the debtor ID.

GET /companylnk/:client_id

Returns the links for a client. Add debtor_id to return a single link.

Optional URL params:

  • debtor_id : limit to a single client/debtor link
  • min_date / max_date : YYYY-MM-DD window on the status date (status_date)
  • last_modified : YYYY-MM-DD (or date-time), returns only links created or changed on/after this time; use for incremental syncs.
  • per_page / page : pagination (cursor supported)

Response example:

{
    "companies_linked": [
        {
            "client_id": "2001",
            "client_name": "Los Angeles Police Credit Un",
            "debtor_id": "3041",
            "debtor_name": "Nelson David L Esq",
            "noa_status": "Acknowledged",
            "status_date": "2010-01-01",
            "note": "NOA on file per debtor reply"
        }
    ],
    "page": 1,
    "per_page": 100,
    "count": 1
}

POST /companylnk/:client_id

Create a new client/debtor link.

Request body (JSON):

  • debtor_id : must be a valid debtor ID. Required.
  • noa_status : one of Created, Sent, Acknowledged, Signed, Released, No Buy. Optional; defaults to Created.
  • note : note stored on the link. Optional.
  • status_date : YYYY-MM-DD. Optional; defaults to today.

The client ID comes from the URL. Posting a link that already exists returns status 400 with "Link already exists - please update instead". The client must be a client and the debtor must be a debtor or the request is rejected.

Request body example:

{
    "debtor_id": 3041,
    "noa_status": "Sent",
    "note": "NOA emailed 2026-06-15"
}

PUT /companylnk/:client_id

Update the NOA status and/or note on an existing client/debtor link.

Querystring parameters:

  • debtor_id : which debtor link under this client to update. Required.
  • noa_status : new status. One of Sent, Acknowledged, Signed, Released, No Buy. Created is not accepted on update. Required.
  • note : note to store on the link. Optional.

Important: This endpoint reads parameters from the querystring. JSON request bodies are ignored.

If no link exists for the client/debtor pair, the request returns status 400 with "Link not found - please create instead". A successful update returns 1.

No-op on unchanged status: if noa_status already matches the current status, the request is a no-op and returns 1 without rewriting the link (the status date and note are left unchanged). This makes the endpoint safe to call repeatedly without overwriting an already-set status. A status change, including moving a link forward (for example Acknowledged to Signed), applies normally.

Example: /companylnk/2001?debtor_id=3041&noa_status=Acknowledged&note=NOA%20on%20file

Client

GET /client/:id

Client ID required. Returns basic client info, along with open A/R total, and reserve total.

Optional URL params:

  • debtorslinked : return debtors linked LNK to the client specified. Response will be Debtor API format.
  • per_page : number of results to return per page (default is 100)
  • page : which page of results to return based on per_page (default is 1)

Response example: /client/1001

{
	"clients": [
		{
			"client_id": "1001",
			"name": "ABC Company Inc",
			"address": "1234 Somestreet 412, San Antonio, TX 78258", 
			"email": "email@yahoo.com", 
			"phone": "555-555-5555", 
			"notes": {
				"funding": "My funding notes.", 
				"verification": "My verification notes.", 
				"warning_status": "Warning status here."
			}, 
			"total_ar": "2389.08", 
			"escrow_reserve": "1876.52", 
			"cash_reserve": "313.90", 
			"metadata": {
				"discount_pct": "0.05",
				"escrow_pct": "0.075"
			},
			"mc_number": "123456"   // if transportation
		}
	]
}

Debtor

GET /debtor/:id

Returns basic debtor info, along with open A/R total, available credit, restricted status, credit report expired (Y/N).

Sub-debtors (debtors linked to a parent/HQ debtor) also include a credit_group block with the parent's hq_id and hq_name, and the group's hq_limit, hq_balance and hq_available_credit, the same available credit the portal shows for that debtor. available_credit itself is unchanged. Debtors without a parent do not include the block.

Optional URL params:

  • searchname : find debtors matching, by Name
  • mc_number : find debtors matching, by MC Number (if transportation)
  • per_page : number of results to return per page (default is 100)
  • page : which page of results to return based on per_page (default is 1)

Response example: /debtor/2003

{
	"debtors": [
		{
			"debtor_id": "2003",
			"name": "XYZ Express LLC",
			"address": "987 Somewhere Rd, San Antonio, TX 78258", 
			"email": "email@example.com", 
			"phone": "555-123-4567", 
			"notes": {
				"billing": "My billing notes.", 
				"collection": "My collection notes.", 
				"receipt": "My receipt notes.", 
				"verification": "My verification notes.", 
				"warning_status": "Warning status here."
			},
			"total_ar": "2389.08", 
			"credit_rating": {
				"agency": "ansonia", 
				"score": "97",
				"avg_days": "37", 
				"date": "2025-10-05"
			},
			"days_to_pay": "43", 
			"available_credit": "129829.92", 
			"restricted": "N", 
			"credit_report_expired": "N", 
			"mc_number": "987654",   // if transportation
			"credit_group": {        // sub-debtors only
				"is_sub": true,
				"hq_id": "2001",
				"hq_name": "XYZ Holdings Inc",
				"hq_limit": "250000.00",
				"hq_balance": "182340.50",
				"hq_available_credit": "67659.50"
			}
		}
	]
}

DebtorCredit

GET /debtorcredit/:id

Debtor ID required. Returns debtor credit history, showing Agency, Score, Avg Days, and date. Most recent entry first.

Optional URL params:

  • per_page : number of results to return per page (default is 100)
  • page : which page of results to return based on per_page (default is 1)

Response example: /debtorcredit/2003

{
	"creditHistory": [
		{
			"debtor_id": "2003",
			"agency": "Ansonia",
			"score": "95", 
			"avg_days": "26", 
			"date": "2025-12-01", 
			"user": "Bob Smith"
		}, 
		{
			...
		}
	]
}

POST /debtorcredit

Create a new debtor credit entry

Required fields: debtor_id, score, agency. Optional fields: rating, avg_days

Request body example:

{
	"debtor_id": "2003",
	"agency": "Ansonia",
	"score": "95", 
	"avg_days": "26"
}

Response example:

"1"

Invoice

GET /invoice

Return a list of invoices

Optional URL params:

  • client_id : results for specific client by their client_id
  • debtor_id : results for specific debtor by their debtor_id
  • inv_no : results for specific invoice number
  • is_purchase : results for purchase (y) or non-purchase (n)
  • status_ap : open or closed results for client funding due (open) or funded (closed)
  • status_ar : open or closed results for debtor receipt balance due (open) or paid in full (closed)
  • min_date=YYYY-MM-DD : results greater than the date specified, by buy_date
  • max_date=YYYY-MM-DD : results less than the date specified, by buy_date
  • last_modified=YYYY-MM-DD HH:MM:SS : invoices whose record changed since the date/time specified. Use this for incremental polling to get only what changed since your last successful pull. Catches new invoices, edits to invoice details, and open/closed status changes. Note: this tracks the invoice record itself, not its individual transactions - use Transaction endpoint's created_min for those specific changes.
  • created_min : the same "last modified since" filter as last_modified, just given as a Unix timestamp instead of a date/time. The name matches the Transaction endpoint so you can reuse one convention - despite the name, it filters on when the invoice was last modified, not when it was created. Use whichever format your integration already uses.
  • created_max : optional upper bound for that same "last modified" filter, as a Unix timestamp. Pair it with created_min to pull a bounded window - for example, backfilling a specific day or hour.
  • per_page : number of results to return per page (default is 100)
  • page : which page of results to return based on per_page (default is 1)
  • cursor : token for cursor-based pagination. Returned in response body as next_cursor when more results are available.
     * Use `cursor` instead of `page` for large or continuous result sets.

Tip for incremental polling:

To mirror your Invoice data without re-pulling overlapping date ranges, save the highest last_modified seen in your last successful pull and use it as the last_modified (or created_min) on the next call. Returns only invoices whose record was added or changed since then. Combine with cursor pagination for large result sets.

Mirroring transactions too?

The Invoice cursor tracks the invoice record (details and open/closed status), not its individual transaction entries. To keep transactions current, poll the Transaction endpoint with created_min on the same incremental schedule. Together they give you a complete, low-bandwidth mirror.

Response example:

{
	"invoices": [
		{
			"inv_id": "10001",
			"client_id": "1001",
			"debtor_id": "2003",
			"inv_no": "1805",
			"inv_ref_no": "12080",
			"other_ref_no": null,
			"client_inv_date": "2025-10-01 05:00:00",
			"buy_date": "2025-10-01 06:00:00",
			"inv_date": "2025-10-01 08:00:00",
			"due_date": null,
			"receipt_date": null, 
			"fee_schedule": "0",
			"is_purchase": "Yes",
			"pmt_type": "ACH", 
			"status_ap": "closed",
			"status_ar": "open",
			"ptp_date": null,
			"followup_date": null,
			"last_modified": "2025-10-02 14:33:10",
			"transactions": [
				{
					"trans_id": "1",
					"inv_id": "10001",
					"client_id": "1001",
					"debtor_id": "2003",
					"gl_code": "1003",
					"amount": "300.00",
					"date": "2025-10-02 06:00:00",
					"note": "Gross",
					"ref_number": "", 
					"trans_date":"2025-10-01 06:00:00"
				},
				{
					... : ...
				}
			],
			"docs": [
				{
					"doc_name": "Setup Doc", 
					"link_url": "https://linkurl/4jenpqv7ptrr.png",
					"share": "Client + Debtor"
				}
			], 
			"memo_count": 3, 
			"entered_by": "Jamie Jones",
			"purchased_by": "Bob Smith"
		},
		{
			... : ...
		}
	],
	"page": 1,
	"per_page": 100, 
	"count": 100, 
	"next_cursor": "eyJkdCI6ICIyMDI1LTA4LTIwVDAwOjAwOjAwWiJ9"

}

GET /invoice/:id

Return a single invoice by specific invoice ID

Response example: /invoice/10026

{
	"id": "10026",
	"client_id": "1001",
	"debtor_id": "2003",
	"inv_no": "74586",
	"inv_ref_no": null,
	"other_ref_no": null,
	"client_inv_date": "2025-10-01 17:00:00",
	"buy_date": "2025-10-01 19:00:00",
	"inv_date": "2025-10-01 19:00:00",
	"due_date": "2025-11-01 19:00:00",
	"receipt_date": "2025-11-01 19:00:00",
	"fee_schedule": "2",
	"is_purchase": "Yes",
	"pmt_type": "ACH", 
	"status_ap": "closed",
	"status_ar": "open",
	"ptp_date": "2025-11-15",
	"followup_date": "2025-11-10",
	"last_modified": "2025-10-12 16:15:03",
	"transactions": [
		{
			"trans_id": 1095,
			"inv_id": "10026", 
			"client_id": "1001",
			"debtor_id": "2003", 
			"gl_code": 1003,
			"amount": "1200.00",
			"date": "2025-10-01 19:00:00",
			"note": "Gross",
			"ref_number": "", 
			"trans_date":"2025-10-01 06:00:00"
		},
		{
			... : ...
		}
	], 
	"docs": [
		{
			"doc_name": "Setup Doc", 
			"link_url": "https://linkurl/4jenpqv7ptrr.png",
			"share": "Client + Debtor"
		}
	], 
	"memo_count": 3, 
	"entered_by": "Jamie Jones",
	"purchased_by": "Bob Smith"
}

GET /preinvoice

Return a list of PRE-invoices. These are entered invoices not yet purchased.

Optional URL params:

  • client_id : results for specific client by their client_id
  • debtor_id : results for specific debtor by their debtor_id
  • min_date=YYYY-MM-DD : results greater than the date specified, by submit_date
  • max_date=YYYY-MM-DD : results less than the date specified, by submit_date
  • per_page : number of results to return per page (default is 100)
  • page : which page of results to return based on per_page (default is 1)

Response example:

{
	"preinvoices": [
		{
			"preinv_id": "10",
			"client_id": "1001",
			"debtor_id": "2003",
			"inv_no": "123456",
			"inv_ref_no": null,
			"other_ref_no": null,
			"inv_comment": "FUEL ADVANCE - Acme Trucking LLC - Load 4471",
			"client_inv_date": "2025-10-01 19:00:00",
			"due_date": "2025-11-01 19:00:00",
			"submit_date": "2025-10-01 19:00:00",
			"invoice_amount": "1000.00", 
			"fees": [
				{
				"gl_code": "2004",
				"amount": "12.00"
				},
				{
				... : ...
				}
			], 
			"client_total_due": "988.00", 
			"fee_schedule": "2",
			"is_purchase": "Yes",
			"docs": [
				{
					"doc_name": "Setup Doc", 
					"link_url": "https://linkurl/4jenpqv7ptrr.png",
					"share": "Client + Debtor"
				}
			]
		{
			... : ...
		}
	],
	"page": 2,
	"per_page": 25, 
	"count": 17
}
				

GET /preinvoice/:id

Return a single PRE-invoice by specific PRE-invoice ID

Response example: /preinvoice/10

{
	"preinv_id": "10",
	"client_id": "1001",
	"debtor_id": "2003",
	"inv_no": "123456",
	"inv_ref_no": null,
	"other_ref_no": null,
	"inv_comment": "FUEL ADVANCE - Acme Trucking LLC - Load 4471",
	"client_inv_date": "2025-10-01 19:00:00",
	"due_date": "2025-11-01 19:00:00",
	"submit_date": "2025-10-01 19:00:00",
	"invoice_amount": "1000.00", 
	"fees": [
		{
			"gl_code": "2004",
			"amount": "12.00"
		},
		{
			... : ...
		}
	], 
	"client_total_due": "988.00", 
	"fee_schedule": "2",
	"is_purchase": "Yes",
	"docs": [
		{
			"doc_name": "Setup Doc", 
			"link_url": "https://linkurl/4jenpqv7ptrr.png",
			"share": "Client + Debtor"
		}
	]
}

GET /importinvoice/:id

Return a single invoice and it's status by YOUR specific external_id.
Only invoices submitted using the POST /importinvoice endpoint below can be requested.

Response example: /importinvoice/123

{
	"external_id": "123",
	"status": "pre-purchase", 
	"client_id": "1001",
	"client_name": "ABC Company Inc", 
	"debtor_id": "2003",
	"debtor_name": "XYZ Express LLC", 
	"invoice_date": "2025-08-01",
	"due_date": "2025-09-01", 
	"invoice_number": "12345",
	"po_ref": "12345",
	"other_ref": "3456",
	"invoice_amount": "1399.00", 
	"invoice_comment": "", 
	"notes": "",							// Internal Memo on the invoice (not shown to the debtor)
	"labels": ["ACH", "Rush"],					// Labels sent with the invoice. [] when none.
	"is_non_purchase": "0",
	"submitted_at": "2025-08-01 10:10:10"
}

POST /importinvoice

Submit an invoice

Required fields: external_id, client_id, debtor_id, invoice_date, invoice_number, invoice_amount

Request body example:

{
	"external_id": 123, 					// Required. YOUR internal id.
	"client_id": 1001,						// Required. FV internal client_id.
	"debtor_id": 2003, 						// Required. FV internal debtor_id.
	"debtor_name": "XYZ Express LLC",
	"invoice_date": "2025-08-01",				// Required. Format YYYY-MM-DD
	"due_date": "2025-09-01",				// Optional. Format YYYY-MM-DD. Defaults to Debtor setting if omitted.
	"invoice_number": "12345",				// Required.
	"po_ref": "12345",
	"other_ref": "3456", 
	"invoice_amount": "1399.00",				// Required. Format 2500.00 (no currency symbol or commas)
	"invoice_comment": "",					// Optional. Comment shown on the invoice itself.
	"notes": "",							// Optional. Populates the Internal Memo on the invoice (not shown to the debtor).
	"labels": ["ACH", "Rush"],					// Optional. Up to 10 labels, 50 characters each. Array or comma-separated string.
	"is_non_purchase": "0",					// Optional. Defaults to "0" if omitted.
	"verification":{						// Optional.
		"state":"verified", 				// Accepted state: altered|pending|review|verified 
		"notes":"any internal notes here",		// Verification notes only -- NOT the Internal Memo (see top-level "notes" above)
		"disclosure_details":[	
			"Verified Rate Agreement", 		// List any specific verification details
			"Client-Debtor Match"
		]
	}, 
	"docs": [
		{
			"doc_name": "Setup Doc", 
			"visibility": {				// See Doc Share meanings below in definitions
				"client": true, 
				"debtor": false
			}, 
			"doc_url": "https://linkurl/4jenpqv7ptrr.png"	// Public URL of document, 25MB limit
		}, 
		{
			"doc_name": "Due dilligence", 
			"visibility": {
				"client": true, 
				"debtor": true
			}, 
			"doc_data": "base64encodedFile=="	// Base64-encoded document data, 25MB limit
		}
	]
}

Response example:

{ external_id : submission_id }
		

If successful you will receive back your external_id along with a submission_id.


GET /invoicememo/:id

Return invoice memo(s) in descending order by specific invoice ID.

Response example: /invoicememo/10026

{
	"inv_id": "10026",
	"client_id": "1001",
	"debtor_id": "2003",
	"inv_no": "74586",
	"memos": [
		{
			"memo": "Invoice has been independantly verified by XYZ Express",
			"date": "2025-09-28 19:00:01", 
			"user": "Bob Smith"
		},
		{
			"memo": "Illegible copies, requested originals",
			"date": "2025-09-27 18:00:01", 
			"user": "Jamie Jones"
		},
		{
			"memo": "Received invoice and paperwork via email",
			"date": "2025-09-26 17:00:01", 
			"user": "Jamie Jones"
		}
	]
}

POST /invoicememo

Create a new memo on an invoice.
Optionally set or clear the invoice's Promise-to-Pay date and/or Follow-up date in the same call.

Required fields: inv_id, memo (where inv_id matches a valid invoice ID)

Optional fields:

  • ptp_date, followup_date : Format for each is YYYY-MM-DD. Updates an invoice's Promise-to-Pay date and/or Follow-up date. Pass empty string ("") to clear. Omit to leave unchanged. Set dates can be read with GET Invoice.

Note: Invalid dates will return HTTP 400 and no memo is created.

Request body example:

{
	"inv_id": "10026",
	"memo": "Invoice has been sent to debtor",
	"ptp_date": "2025-11-15",			// optional. See above.
	"followup_date": "2025-11-10"			// optional. See above.
}

Response example:

 "success" 

Transaction

GET /transaction

Return a list of accounting transactions

Optional URL params:

  • client_id : results for specific client ID (client_id)
  • debtor_id : results for specific debtor ID (debtor_id)
  • inv_id : results for a specific invoice ID (inv_id)
  • gl_code : filter by a single GL code (gl_code)
  • gl_codes : filter by multiple GL codes (comma-separated). Example: gl_codes=1000,1100,2004
  • bank_account : filter by bank account code (see /transaction/bankaccounts). Requires min_date/max_date, client_id, debtor_id, inv_id or batch_id alongside it, else 400. Example: bank_account=operating-1&min_date=2025-09-01
  • batch_id : filter by a single posting batch
  • batch_ids : filter by multiple batches (comma-separated). Example: batch_ids=123,124
  • created_min : filter by minimum creation unix timestamp
  • created_max : filter by maximum creation unix timestamp
  • min_date=YYYY-MM-DD : results greater than the date specified, by date
  • max_date=YYYY-MM-DD : results less than the date specified, by date
  • per_page : number of results to return per page (default is 100)
  • page : which page of results to return based on per_page (default is 1)
  • cursor : token for cursor-based pagination. Returned in response body as next_cursor when more results are available.
     * Use cursor instead of page for large or continuous result sets.

Clarifications:
• gl_code – corresponds to the ledger account / GL code definition in /transaction/types.
• date – the posting date used for accounting and reporting (may be system-set or adjusted).
• trans_date – the effective/business date entered by a user (for example, a selected fund date).
• batch_id – groups transactions created as part of the same posting action (payment, deposit, fees, reserve movements).
• bank_account – which of your own accounts the funds moved through, as {"code": ..., "name": ...}.
• created_ts – when the transaction was created (system-generated, unix timestamp).

Request examples:

GET /transaction/?inv_id=10026
GET /transaction/?inv_id=10026&gl_code=1003
GET /transaction/?min_date=2025-09-01&max_date=2025-10-31&gl_codes=1000,1001,1003
GET /transaction/?client_id=1001&gl_codes=1000,2004&per_page=500
GET /transaction/?bank_account=operating-1&min_date=2025-09-01&max_date=2025-10-31
GET /transaction/?bank_account=operating-1&client_id=1001

Response example:

{
    "transaction_list": [
        {
			"trans_id": "1095",
			"inv_id": "10026",
			"client_id": "1001",
			"debtor_id": "2003",
			"gl_code": "1003",
			"amount": "1200.00",
			"date": "2025-10-01 19:00:00",
			"note": "Gross",
			"ref_number": "", 
			"trans_date":"2025-10-01 06:00:00", 
			"batch_id": "12345",
			"created_ts": "1759322121"
		}, 
		{
			... : ... 
		}
	], 
	"page": 1,
	"per_page": 100, 
	"count": 100, 
	"next_cursor": "eyJkdCI6ICIyMDI1LTA4LTIwVDAwOjAwOjAwWiJ9"
}

Note: pmt_type is included only for payment transactions (gl_code = 1000) and is omitted for all other transaction types.
bank_account is included only on gl_code 1000 and 1001, and omitted when not set or no longer configured. Code and display name only, never account or routing numbers.
Example:

{
	"trans_id": "1102",
	"inv_id": "10026",
	"client_id": "1001",
	"debtor_id": "2003",
	"gl_code": "1000",
	"amount": "-1100.00",
	"date": "2025-10-05 15:32:00",
	"note": "Payment received",
	"ref_number": "ACH-849302",
	"pmt_type": "ACH",
	"bank_account": {
		"code": "operating-1",
		"name": "Operating Account"
	},
	"trans_date": "2025-10-05 08:32:00",
	"batch_id": "23456",
	"created_ts": "1759674741"
}

GET /transaction/:id

Return a single transaction by transaction ID (trans_id).
To return all transactions for an invoice, use GET /transaction/?inv_id=<invoice_id>.

Optional fields such as pmt_type are conditionally included based on transaction type.

Response example: /transaction/1095

{
	"trans_id": "1095",
	"inv_id": "10026",
	"client_id": "1001",
	"debtor_id": "2003",
	"gl_code": "1003",
	"amount": "1200.00",
	"date": "2025-10-01 19:00:00",
	"note": "Gross",
	"ref_number": "", 
	"trans_date":"2025-10-01 06:00:00", 
	"batch_id": "12345",
	"created_ts": "1759322121"
} 

Transaction Types

GET /transaction/types

Return a list of accounting transaction types (ledger accounts definition)

Response example:

[
	{
		"gl_code": "1000",
		"gl_description": "Payments to Client",
		"gl_type": "BANK"
	},
	{
		"gl_code": "1001",
		"gl_description": "Payment Received from Debtor",
		"gl_type": "OCASSET"
	},
	{
		"gl_code": "1003",
		"gl_description": "Factored Receivables",
		"gl_type": "OCASSET"
	}
]

GET /transaction/bankaccounts

Return your company's configured bank accounts as code and display name. These are the valid values for the bank_account filter.

Configured selections only – no account numbers, routing numbers, or client bank records.

Response example:

[
	{
		"code": "operating-1",
		"name": "Operating Account"
	},
	{
		"code": "lockbox-a",
		"name": "Lockbox A"
	},
	{
		"code": "payables",
		"name": "Payables Account"
	}
]

Action Item

GET /actionitem/:client_id

Client ID required. Returns action items on invoices for the specified Client, with most recently added items first.

Optional URL params:

  • invoice_id : return action items for a single invoice ID. Client ID may be 0 for an invoice lookup.
  • all : return Open and Closed action items (default is Open only)
  • min_date=YYYY-MM-DD : results greater than the date specified, by date_added
  • max_date=YYYY-MM-DD : results less than the date specified, by date_added
  • per_page : number of results to return per page (default is 100)
  • page : which page of results to return based on per_page (default is 1)

Request examples:

GET /actionitem/1001
GET /actionitem/0?invoice_id=10026
GET /actionitem/1001?all&min_date=2025-10-01

Response example:

{
    "actionItems": [
        {
            "invoice_id": "10026",
            "client_id": "1001", 
            "debtor_id": "2003", 
            "debtor_name": "XYZ Express LLC",
            "invoice_number": "74586",
            "invoice_date": "2025-10-01",
            "invoice_amount": "123.00",
            "action_item_id": "21",
            "action_item_name": "Illegible Copies",
            "date_added": "2025-10-02",
            "added_by": "Bob Smith",
            "date_closed": "2025-10-05", 
            "age": "3"
        }
    ]
}

POST /actionitem

Attach an action item to an invoice.

Request body (JSON):

  • invoice_id : must be a valid invoice ID. Required.
  • action_item_id : must be a valid (and active) action item ID. Required.
  • notify : when 1, sends the standard in-app notification. Optional (0 or 1).
  • note : message included in the notification only. This value is not stored or returned on the action item. Optional.

The request is idempotent. If the same action item is already open on the invoice, the existing attachment is returned with status 200 instead of creating a duplicate; a new attachment returns 201. The response body is a single action item in the same shape as the GET results, including invoice_id and action_item_id.

Request body example:

{
    "invoice_id": 10026,
    "action_item_id": 21,
    "notify": 1
}

PUT /actionitem/:invoice_id

Close or reopen an action item on an invoice.

Querystring parameters:

  • action_item_id : which action item on this invoice to update. Required.
  • reopen=1 : reopen instead of close. Optional; omit to close.

Important: This endpoint reads parameters from the querystring. JSON request bodies are ignored.

Close (the default) sets the closed date on every matching action item for the invoice, collapsing any duplicates into one close. Reopen (reopen=1) clears the closed date; it is a no-op when an open row already exists, otherwise it reopens the most recently closed match. The response body is the updated action item in the same shape as the GET results.

Examples. Close: /actionitem/10026?action_item_id=21   Reopen: /actionitem/10026?action_item_id=21&reopen=1

Action Item Types

GET /actionitem/types

Returns a list of action items available for your account.
The returned id is the action_item_id for use in POST or PUT /actionitem.

Optional URL params:

  • all : include inactive items (default is active items only)

Request examples:

GET /actionitem/types
GET /actionitem/types?all

Response example:

[
	{
		"id": "21",
		"action_item_name": "Illegible Copies",
		"active": "1"
	},
	{
		"id": "8",
		"action_item_name": "Short Pay",
		"active": "1"
	}
]

Pagination and Limits

Result Limits

  • By default, up to 100 results are returned.
  • You can adjust with per_page between 1 and 1,000.
  • Requests larger than 1,000 are automatically capped.

Cursor-based Pagination, if available (recommended)

Cursor pagination ensures consistent ordering and avoids duplicates when traversing large or capped ranges.

  • Each response may include a next_cursor in both the JSON body and headers.
  • Pass this value back as cursor on your next request.
  • Continue until no next_cursor is returned.
  • You may combine per_page with cursor to control batch size (e.g. ?per_page=500&cursor=...).

Example:

{
  "invoices": [
    { "inv_id": "10001", "client_id": "1001", ... },
    ...
  ],
  "page": 1,
  "per_page": 100, 
  "count": 100, 
  "next_cursor": "eyJkdCI6ICIyMDI1LTA4LTIwVDAwOjAwOjAwWiJ9"
}

Example request (fetch next batch):

GET /invoice?cursor=eyJkdCI6ICIyMDI1LTA4LTIwVDAwOjAwOjAwWiJ9

Response headers:

X-Next-Cursor: eyJkdCI6ICIyMDI1LTA4LTIwVDAwOjAwOjAwWiJ9

Page-based Pagination

  • You may continue using ?page=2, ?page=3, etc. in combination with per_page.
  • Less efficient for large queries: capped ranges (e.g. 90 days) may end after only a few pages.

Date range limits

Large or open-ended date ranges may be automatically reduced to improve performance.

  • Requests without a min_date or max_date will default to a 90-day window.
  • If only min_date is given, the range will extend forward 90 days (in ASC order).
  • If only max_date is given, the range will backfill 90 days (in DESC order).
  • Headers X-Window-Applied and X-Window-Reason indicate when limits or ordering have been applied.

Best Practices

  • Prefer cursor pagination over page numbers.
  • Use per_page with cursor to tune batch size.
  • Always check next_cursor in the response body or X-Next-Cursor header.
  • Narrow date ranges where possible for faster queries.

Incremental Sync (recommended pattern)

If you keep a local copy of your data in sync, poll for what changed rather than re-requesting a rolling date window on every cycle. A window re-pull returns mostly records you already have. Combining last_modified with cursor keeps each cycle proportional to your actual change volume.

The pattern:

  1. Store the timestamp of your last successful pull (the watermark). Start it at whatever backfill point you need.
  2. Request with last_modified set to that watermark.
  3. Follow next_cursor until it comes back empty. Do not restart from page 1.
  4. Only after the full cycle succeeds, advance the watermark to the time you started the cycle.
  5. Repeat on a schedule. Hourly is sufficient for nearly all workflows.

First cycle:

GET /api/v1/invoice?last_modified=2026-06-01 08:00:00&per_page=250

Response (truncated):

{
	"invoices": [ ... ],
	"next_cursor": "eyJkdCI6ICIyMDI2LTA3LTIxVDA5OjE0OjAwWiJ9",
	"per_page": 250,
	"count": 250
}

Continue the same cycle by passing the cursor back. Keep last_modified unchanged for the whole cycle:

GET /api/v1/invoice?last_modified=2026-06-01 08:00:00&per_page=250&cursor=eyJkdCI6ICIyMDI2LTA3LTIxVDA5OjE0OjAwWiJ9

When next_cursor comes back empty, the cycle is complete. Advance your watermark to 2026-06-01 08:00:00 plus the cycle start offset and wait for the next scheduled run.

Where incremental filters are available

min_date / max_date filter on a business date, not on change. A sliding window returns the same records every cycle. Use these instead:

  • last_modified - /company, /companylnk, /invoice
  • created_min / created_max - /invoice; created_min only - /companylnk. Same filter, Unix timestamp form.
  • created_min / created_max - /transaction. Filters on creation, not later edits. Pair with /invoice + last_modified to catch both.
  • Anything else: narrow min_date / max_date plus cursor. See Date range limits.

Patterns to avoid

  • Using min_date / max_date as a change filter. A sliding window re-reads the same records every cycle. Use last_modified or created_min.
  • Restarting pagination from page 1 each cycle. Deep back-pages are the most expensive requests you can make.
  • Polling faster than hourly without a matching change rate. It multiplies request count without returning more data.
  • Re-authenticating on every request. Session tokens are valid for 15 minutes; reuse the token until it expires.
  • Ignoring Retry-After on a 429. Back off for the interval given.

Default ordering

Results are sorted newest-first (DESC) unless otherwise specified. Request specific order with order = asc/desc.

Miscellaneous Definitions

Document Visibility, also seen as "Doc Share"

This value determines who has visibility of the document. The factor always sees all documents.

"visibility": {
	"client": true,		// client sees documents
	"debtor": true			// debtor sees documents, and are included with invoice submissions
}

Some areas display current visibility settings in this way:

{[ "0": "Factor Only", "1": "Client Only", "2": "Client + Debtor", "3": "Debtor Only" }