Data Access provides an FDX API to third-party applications (data recipients) for tokenized, secure access to consumer financial data. This includes accounts, transactions, and personal identifying information (PII). The API uses the FDX 4.6 standard for data fetching as well as OpenID Connect (OIDC) for authentication and authorization.
This page gives data recipients much of the information they’ll need to use this API.
Every new data recipient needs to start with the following tasks, regardless of your particular use case. These will ensure your integration has the fewest possible complications.
customer
, account
and transaction
resources. To obtain this information this, you’ll need to register on the official FDX website.Data recipients can access three core resources through this API: customers
, accounts
, and transactions
.
A customer
represents the end user whose data you wish to access.
An account
represents an account with a financial institution such as CHECKING
or SAVINGS
. An account
belongs to the customer
.
A transaction
represents a financial transaction either flowing into or out of an account. A transaction
belongs to an account
.
Status code | Definition |
---|---|
400 Bad Request |
|
401 Unauthorized |
|
429 Too Many Requests |
The number of requests has exceeded the rate limit for the data recipient. |
Requests are rate limited for all data recipients on all FDX and client-initiated OAuth endpoints. However, this limit is not fixed and can be adjusted upon request to facilitate changes in application features that require increased volume.
If the rate limit has been reached, the API will return a 429 Too Many Requests
status along with an error message.
1
2
3
4
5
6
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
{
"error": "too many requests"
}
To access the API, data recipients can register on the developer portal if acting as an intermediary, or provide the required information to the data provider via email.
After the request for access has been approved, you will be given a dynamic client registration API key or a list of client IDs and secrets for all submitted applications.
Required Information
All requests to FDX endpoints must include a customer-scoped token issued from the OIDC /api/v1/oauth/token
endpoint. This token must be passed in the Authorization
header with the type Bearer
as shown in the example.
All requests from data recipients must originate from a predetermined IP or CIDR range set during the onboarding process. All requests originating from IPs outside of these will result in a 401 Unauthorized
status from the API, regardless of whether the request contains a valid customer token.
401 Uauthorized
is also returned if the client and/or application has been given a status of disabled
.
Endpoint:
GET /api/v1/fdx/customers/current
1
2
3
curl https://base.url.com/api/v1/fdx/customers/current
-H Authorization: Bearer ${customer_scoped_access_token}
-H Accept: application/json
1
HTTP/1.1 401 Unauthorized
Specification: https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.1
Query Parameters
Name | Required? | Notes |
---|---|---|
client_id |
Yes | — |
redirect_uri |
Yes | — |
response_type |
Yes | code is the only supported response type. |
code_challenge |
Yes | PKCE code challenge. https://datatracker.ietf.org/doc/html/rfc7636 |
code_challenge_method |
Yes | Must be set to S256 . |
scope |
Yes | See scopes table. |
state |
No | An opaque value used by the client to maintain state between the request and callback. https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-00#section-4.1.1.3 |
Available Scopes
Name | Required? | FDX Resource Access |
---|---|---|
openid |
Yes | Any |
customers |
No | /customers/current |
accounts |
No | /accounts /accounts/{accountId} |
transactions |
No | /accounts/{accountId}/transactions |
statements |
No | TBD |
Endpoint:
GET /oauth2/v4/authorize
1
2
curl -i -X GET 'https://base.url.com/oauth2/v4/authorize?client_id=8-NKBucVBblNc1LUlok76nz0-JpG8qWAXPIPf2P1NBA&redirect_uri=https%3A%2F%2Fcentzy.org%2Foidc_callback&response_type=code&code_challenge=uR7wSgfQ1JGJBevOjxefcyWnkX4SpclYyxorm10tBIY&code_challenge_method=S256&scope=openid+customers+accounts+transactions&state=YW55dGhpbmcgeW91IG5lZWQ='
-H 'Accept: application/x-www-form-urlencoded'
1
https://centzy.org/oidc_callback?code=SplxlOBeZQQYbYS6WxSbIA&state=YW55dGhpbmcgeW91IG5lZWQ=
Specification: https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.3
Use this endpoint to get an access token or refresh token. This endpoint uses client_secret_basic
authorization.
All issued refresh tokens expire after 30 days. Refresh tokens are rotated upon use in the refresh_token
flow
with a new token in the response.
All issued tokens are opaque (reference tokens).
Parameters
Name | Required? | Notes |
---|---|---|
client_id |
Yes | —— |
code |
Yes | The authorization code obtained from the authorize endpoint. |
grant_type |
Yes | Only authorization_code and refresh_token grant types supported. |
redirect_uri |
Required if used with the authorize endpoint. | —— |
Endpoint:
POST /oauth2/v4/token
1
2
3
4
5
curl -i -X POST "https://base.url.com/oauth2/v4/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Accept: application/json' \
-H 'Authorization: Basic Y2xpZW50X2lkOnNlY3JldA==' \
-d 'grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fcentzy.org%2Foidc_callback'
1
2
3
4
5
6
7
{
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"example_parameter": "example_value",
"expires_in": 3600,
"refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
"token_type": "example"
}
Specification: https://datatracker.ietf.org/doc/html/rfc7009#section-2.1
Use this endpoint to revoke an access token or refresh token.
Parameters
Name | Required? | Notes |
---|---|---|
token |
Yes | The token to be revoked. |
token_type_hint |
No | The type of token. Can be either access_token or refresh_token . |
Endpoint:
POST /oauth2/v4/revoke
1
2
3
4
curl -i -X POST 'https://base.url.com/oauth2/v4/revoke' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Authorization: Basic Y2xpZW50X2lkOnNlY3JldA==' \
-d 'token=SplxlOBeZQQYbYS6WxSbIA&token_type_hint=access_token'
1
200 OK
This page does not include the full FDX specification. To obtain it, you must register on the official FDX website.
However, we have included a list of available FDX 4.6 endpoints and some general information about them here.
The query parameters listed are those supported by default. Particular instances of Data Access may support more.
FDX endpoint | Supported Query Parameters | Description |
---|---|---|
/fdx/v4/accounts/{accountId}/transactions |
startTime endTime offset limit |
Returns a list of FDX transactions. |
/fdx/v4/accounts/{accountId} |
— | Returns details for the specified account. |
/fdx/v4/accounts |
accountIds offset limit |
Returns a collection of lightweight FDX accounts. |
/fdx/v4/capability |
— | Returns the capabilities of the FDX API. |
/fdx/v4/customers/current |
— | Returns PII including name, dob, email, addresses, phone numbers. |
This API supports the automated onboarding for data recipient applications, called Dynamic Client Registration (DCR). It follows OAuth specification RFC7951 with some limitatations and other minor enhancements. A special DCR token will be issued upon initial data recipient approval. This token must be passed in the authorization header, e.g., Authorization: Bearer ${DCR token}
DCR requests must originate from a whitelisted IP address configured during the onboarding process.
Available Endpoints
Endpoint | Description |
---|---|
POST /oauth2/v4/register |
Creates and returns a new client. |
GET /oauth2/v4/register/${client_id} |
Returns information about the specified client. |
PUT /oauth2/v4/register/${client_id} |
Updates and returns information about the specified client. |
DELETE /oauth2/v4/register/${client_id} |
Deletes the specified client. |
Field | Data Type | Description |
---|---|---|
categories |
Array | An array of categories passed when creating the client. |
client_id |
String | The unique identifier for the client. Defined by the API. |
client_id_issued_at |
Integer | The date and time the client_id was issued, given in Unix time. |
client_name |
String | The human-readable name of the client. |
client_secret |
String | The client secret issued by the API. |
client_secret_expires_at |
Integer | The date and time at which the client secret expires, given in Unix time. 0 indicates the client secret does not expire. Defaults to 0 . |
grant_types |
Array | The grant types issued to the client. |
logo_uri |
String | A URI pointing to a logo for the client application. |
redirect_uris |
Array | An array of redirect URIs. |
software_id |
String | The unique identifier for the client application. Defined by the data recipient when creating the client. |
Use this endpoint to create a new client. This endpoint expects a JSON object in the request body with the following attributes defined:
Parameters
Name | Required? | Notes |
---|---|---|
categories |
No | — |
client_name |
Yes | — |
grant_type |
Yes | Only authorization_code type supported; refresh_token is implied. |
logo_uri |
No | — |
redirect_uris |
Yes | Currently, this array must contain only one URI. |
scope |
Yes | A space-separated list of customer data access rights desired for the client. This list must contain openid and may contain any subset of the available scopes:customers accounts transactions statements offline_access is implied and does not need to be provided. |
software_id |
Yes | — |
Endpoint:
POST /oauth2/v4/register
1
2
3
4
5
6
7
8
9
10
11
12
13
14
curl -i -X POST 'https://base.url.com/oauth2/v4/register' \
-H 'Authorization: Bearer 3cfb93d5-5d87-46e7-b9a6-358c63b8c4cb' \
-H 'Content-Type: application/json' \
-d '{
"categories": "budgeting,investments,healthcare",
"client_name": "Centz",
"grant_type": "authorization_code",
"logo_uri": "https://centz.example.org/logo.svg",
"redirect_uris": [
"https://centz.example.org/redirect"
],
"scope": "openid customers accounts transactions",
"software_id": "CENTZ-2408aef1-7a67-470c-94a6-a2bba80ebee9"
}'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"categories": [
"budgeting",
"investments",
"healthcare"
],
"client_id": "yeh8XywAkX101r_Tb_DCtJ_ukxc5lx88qOVPtKdqtmI",
"client_id_issued_at": 1650055408,
"client_name": "Centz",
"client_secret": "UQc-XiTdZMm1x6PYI0FMv_AfJZIVOpeBzdrwiWyQOv8",
"client_secret_expires_at": 0,
"grant_types": [
"authorization_code",
"refresh_token"
],
"logo_uri": "https://centz.example.org/logo.svg",
"redirect_uris": [
"https://centz.example.org/redirect"
],
"software_id": "CENTZ-2408aef1-7a67-470c-94a6-a2bba80ebee9"
}
1
2
3
4
5
6
7
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error":"invalid_client_metadata",
"error_description":"Scope account is not a permitted scope"
}
1
HTTP/1.1 401 Unauthorized
1
2
3
4
5
6
7
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error":"invalid_redirect_uri",
"error_description":"Validation failed: Redirect uri must use https"
}
Use this endpoint to read the details of the specified client.
Endpoint:
GET /oauth2/v4/register/{client_id}
1
2
3
curl -i -X GET 'https://base.url.com/oauth2/v4/register/yeh8XywAkX101r_Tb_DCtJ_ukxc5lx88qOVPtKdqtmI' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer 3cfb93d5-5d87-46e7-b9a6-358c63b8c4cb'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"categories": [
"budgeting",
"investments",
"healthcare"
],
"client_id": "yeh8XywAkX101r_Tb_DCtJ_ukxc5lx88qOVPtKdqtmI",
"client_id_issued_at": 1650055408,
"client_name": "Centz",
"client_secret": "UQc-XiTdZMm1x6PYI0FMv_AfJZIVOpeBzdrwiWyQOv8",
"client_secret_expires_at": 0,
"grant_types": [
"authorization_code",
"refresh_token"
],
"logo_uri": "https://centz.example.org/logo.svg",
"redirect_uris": [
"https://centz.example.org/redirect"
],
"software_id": "CENTZ-2408aef1-7a67-470c-94a6-a2bba80ebee9"
}
Use this endpoint to update the attributes of the specified client.
Parameters
Name | Required? | Notes |
---|---|---|
categories |
No | —— |
client_name |
No | —— |
logo_uri |
No | —— |
redirect_uris |
No | —— |
software_id |
No | —— |
Endpoint:
PUT /oauth2/v4/register/{client_id}
1
2
3
4
5
6
7
8
9
10
curl -i -X PUT 'https://base.url.com/oauth2/v4/register/yeh8XywAkX101r_Tb_DCtJ_ukxc5lx88qOVPtKdqtmI' \
-H 'Authorization: Bearer 3cfb93d5-5d87-46e7-b9a6-358c63b8c4cb' \
-H 'Content-Type: application/json' \
-d '{
"client_name": "Centz",
"software_id": "CENTZ-2408aef1-7a67-470c-94a6-a2bba80ebee9",
"redirect_uris": ["https://centz.example.org/redirect"],
"categories": "budgeting,investments,healthcare",
"logo_uri": "https://centz.example.org/logo.svg"
}'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"categories": [
"budgeting",
"investments",
"healthcare"
],
"client_id": "yeh8XywAkX101r_Tb_DCtJ_ukxc5lx88qOVPtKdqtmI",
"client_id_issued_at": 1650055408,
"client_name": "Centz",
"client_secret": "UQc-XiTdZMm1x6PYI0FMv_AfJZIVOpeBzdrwiWyQOv8",
"client_secret_expires_at": 0,
"grant_types": [
"authorization_code",
"refresh_token"
],
"logo_uri": "https://centz.example.org/logo.svg",
"redirect_uris": [
"https://centz.example.org/redirect"
],
"software_id": "CENTZ-2408aef1-7a67-470c-94a6-a2bba80ebee9"
}
Use this endpoint to delete the specified client.
Endpoint:
DELETE /oauth2/v4/register/{client_id}
1
2
curl -i -X DELETE 'https://base.url.com/oauth2/v4/register/yeh8XywAkX101r_Tb_DCtJ_ukxc5lx88qOVPtKdqtmI' \
-H 'Authorization: Bearer 3cfb93d5-5d87-46e7-b9a6-358c63b8c4cb'
Name | Data Type | Description |
---|---|---|
theme.brand100 |
String | Hex color value. Used as a background for selected or active elements. Almost always paired with brand400 . |
theme.brand300 |
String | Hex color value. The most prominent brand color. Used for primary buttons. |
theme.brand400 |
String | Hex color value. Used as the foreground color for selected and active elements. |
theme.institution_name |
String | The human-readable name of the financial institution. |
theme.logo.name |
String | The name and extension of the logo file. |
theme.logo.size |
Integer | The size in bytes of the logo file. |
theme.logo.url |
String | The relative URL of the image. |
theme.logo |
Object | JSON object containing all information regarding the logo. |
theme |
Object | JSON object containing all theming information. |
For convenience, this API also includes an endpoint for getting information about brand colors, the logo, and the institution name that can be used for data-recipient UI theming to better match the financial institution. This is considered public information and does not require any client authentication to view.
Endpoint:
GET /settings
1
2
curl -i -X GET 'https://base.url.com/settings' \
-H 'Accept: application/json'
1
2
3
4
5
6
7
8
9
10
11
12
13
{
"theme": {
"brand100": "#F3F9FC",
"brand300": "#188CBB",
"brand400": "#0F759F",
"institution_name": "Epic Bank",
"logo": {
"name": "logo.svg",
"size": 12182,
"url": "/images/logo.svg"
}
}
}