Overview
The Financing Contracts API lets a financier have a loan repaid through Uber. The financier pays out the loan outside Uber and creates a contract through this API. Once the borrower accepts the contract and its start date arrives, Uber retains part of the borrower’s earnings in each retention period and pays it to the financier. Retention continues until the loan is repaid, the contract reaches its end date, or the contract is terminated.
Your organization is the lender. It uses these endpoints to create contracts, read them, lower their retention amounts, record adjustments and terminate them. The borrower is the supplier organization repaying the loan. It accepts or rejects each new contract in Supplier Portal.
¶ Endpoints
| Endpoint | Method | Resource | Rate limit |
|---|---|---|---|
| Create Contract | POST |
/v1/vehicle-supplier/financing/contracts |
5 per hour |
| Get Contract | GET |
/v1/vehicle-supplier/financing/contracts/:contract_id |
10 per second |
| Search Contracts | POST |
/v1/vehicle-supplier/financing/contracts/search |
10 per second |
| Update Contract | PATCH |
/v1/vehicle-supplier/financing/contracts/update |
1 per hour |
| Terminate Contract | PATCH |
/v1/vehicle-supplier/financing/contracts/terminate/:contract_id |
5 per hour |
| Adjust Contract | PATCH |
/v1/vehicle-supplier/financing/contracts/adjust |
1 per hour |
Rate limits apply to each developer application, across all of its contracts. A request over the limit fails with HTTP 429.
¶ Access
Every request needs an access token from the Client Credentials flow with the vehicle_suppliers.financing.contracts scope.
Uber also has to enable your application for the Financing Contracts API. Until then, every request fails with 401 and code permission-denied.
The user that the access token represents also needs this permission on your lender organization:
| Permission | Required for |
|---|---|
supplier.contracts.write |
Create Contract, Update Contract, Terminate Contract, Adjust Contract |
supplier.contracts.read |
Get Contract, Search Contracts |
Without it, requests fail with 401 and code permission-denied, even when the token has the right scope. Contact your Uber POC if you need your application enabled or these permissions granted.
¶ Organization IDs
lenderId is your organization’s ID and borrowerId is the borrower’s. Both are organization UUIDs that your Uber POC provides. Encrypted organization IDs returned by other Vehicle Supplier APIs don’t work with these endpoints.
¶ Contract lifecycle
The table shows state names without the CONTRACT_STATE_ prefix. Contract state and State reason list the full values.
| From | To | When |
|---|---|---|
| None | DRAFT |
You call Create Contract. |
DRAFT |
PENDING_ACCEPTANCE |
Uber finishes setting up the contract. |
PENDING_ACCEPTANCE |
ACCEPTED |
The borrower accepts, or the contract is accepted automatically. |
PENDING_ACCEPTANCE |
TERMINATING |
The borrower rejects the contract, you terminate it, or acceptanceExpiryAt passes. |
ACCEPTED |
ACTIVE |
startsAt arrives. |
ACCEPTED |
TERMINATING |
You terminate the contract, or Uber can’t set up retention for the borrower. |
ACTIVE |
TERMINATING |
You terminate the contract, the loan is repaid, or endsAt arrives. |
TERMINATING |
TERMINATED |
A grace period passes. |
TERMINATED is final. Uber stops retaining when a contract enters TERMINATING, and termination doesn’t return amounts already retained.
If Uber has set up automatic acceptance between your organization and the borrower, new contracts skip the borrower’s review and are accepted with reason CONTRACT_STATE_REASON_AUTO_ACCEPTED.
¶ Asynchronous processing
Create Contract, Update Contract, Terminate Contract and Adjust Contract respond as soon as Uber accepts the request, and Uber applies the change afterwards. A 200 response means the request passed validation. It doesn’t confirm that the change took effect, so call Get Contract to check.
- A new contract may not be returned by Get Contract or Search Contracts straight away. If Get Contract returns
not-foundjust after you create a contract, retry after a few seconds. - Uber checks the contract’s state again before it applies a change. If the state changed in the meantime, for example because the contract was terminated, the change isn’t applied.
¶ Retention
retentionConfig.retentionAmount sets how much Uber retains in each retention period. retentionConfig.cadence sets the period, a week or a month.
| You set | Uber retains in each period |
|---|---|
percentRate only |
percentRate percent of the borrower’s earnings |
maxCadenceCap only |
30% of the borrower’s earnings, up to maxCadenceCap |
| Both | percentRate percent of the borrower’s earnings, up to maxCadenceCap |
Uber retains from the earnings of the borrower organization and the organizations below it in its hierarchy, counting only organizations in the contract’s country (metadata.countryIso2). Uber fixes this list of organizations when the contract is accepted. Organizations the borrower adds later aren’t included.
Retention continues until the remaining balance reaches zero. The balance starts at loanAmount. Retention and credit adjustments lower it, and debit adjustments raise it. Uber doesn’t add interest.
¶ Request and response format
- Field names are in lowerCamelCase.
- IDs are UUID objects and times are Timestamp objects. Both have the shape
{"value": ...}. - Timestamps are Unix epoch times in milliseconds.
- Money is an Amount object.
amountE5is the amount multiplied by 100,000, so1500000000means 15,000.00. - Responses return 64-bit integers, such as
amountE5and timestamp values, as strings. Requests can send them as numbers or strings. - Responses leave out fields that are empty or zero. For example, an amount of 0 comes back as
{"currencyCode": "USD"}.
¶ Errors
Error responses have this body:
{
"code": "invalid-effective-start-date",
"message": "<description of the problem>",
"retryable": false
}
| Name | Type | Description |
|---|---|---|
code |
string | Error code. Each endpoint page lists the codes it returns. |
message |
string | Human-readable description. Use it for logging, not in program logic, because the wording can change. |
retryable |
bool | true when the same request can succeed later. Treat a missing value as false. |
Any endpoint can return these errors:
| HTTP status | Code | Meaning |
|---|---|---|
401 |
unauthorized |
The access token is missing, or it doesn’t have the vehicle_suppliers.financing.contracts scope. |
401 |
permission-denied |
Uber hasn’t enabled your application for this API, or the token’s user doesn’t have the required permission. See Access. |
500 |
internal-server-error |
Uber couldn’t process the request. Retry with exponential backoff. |
503 |
service_unavailable |
The service is temporarily unavailable. Retry with exponential backoff. |
When you retry Create Contract or Adjust Contract, send the same idempotencyKey as in the original request.