Sync Transactions

Sync Transactions

Provides a paginated feed of transactions, grouped into created, updated, and removed lists.

Each call will also return a cursor.next value. In subsequent calls, include that value to receive only changes that have occurred since the previous call. Note that these lists are unordered, so it is possible to get transactions with dates that precede those you've fetched in previous calls to this endpoint. Older transactions can be added, for example, when historical data becomes accessible later.

Pending transactions will only be reported as created. Pending transactions are completely removed and replaced with each transaction refresh or update; no attempt is made to track their removal or modification. Pending transactions will not be reported in the removed list. If you store pending transactions, you should remove and replace them entirely each time you fetch new transactions.

Large numbers of transactions will be paginated, and the has_more field will be true. You should continue calling this endpoint with each new cursor.next value until has_more is false.

Note that this endpoint does not trigger a fetch of transactions from the institution; it merely returns transactions that have already been fetched, either because prefetch was requested when the link was created, or because of scheduled or on-demand updates.

MoneyKit checks for updated account data, including transactions, periodically throughout the day, but the update frequency can vary, depending on the downstream data provider, the institution, and whether one or both provide webhook-based updates. To force a check for updated transactions, you can use the /products endpoint.

Note also that the transactions.updates_available webhook will alert you when new data is available.

URL

GET
/links/{id}/transactions/sync
Request
curl --request GET \
--url 'https://api.moneykit.com/links/[id]/transactions/sync?cursor=SOME_STRING_VALUE&size=SOME_INTEGER_VALUE' \
--header 'Authorization: Bearer REPLACE_BEARER_TOKEN'
const options = {method: 'GET', headers: {Authorization: 'Bearer REPLACE_BEARER_TOKEN'}};

fetch('https://api.moneykit.com/links/[id]/transactions/sync?cursor=SOME_STRING_VALUE&size=SOME_INTEGER_VALUE', options)
.then(response => response.json())
.then(response => console.log(response))
.catch(err => console.error(err));
import requests

url = "https://api.moneykit.com/links/[id]/transactions/sync"

querystring = {"cursor":"SOME_STRING_VALUE","size":"SOME_INTEGER_VALUE"}

headers = {"Authorization": "Bearer REPLACE_BEARER_TOKEN"}

response = requests.request("GET", url, headers=headers, params=querystring)

print(response.text)
package main

import (
"fmt"
"net/http"
"io/ioutil"
)

func main() {

url := "https://api.moneykit.com/links/[id]/transactions/sync?cursor=SOME_STRING_VALUE&size=SOME_INTEGER_VALUE"

req, _ := http.NewRequest("GET", url, nil)

req.Header.Add("Authorization", "Bearer REPLACE_BEARER_TOKEN")

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)

fmt.Println(res)
fmt.Println(string(body))

}
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://api.moneykit.com/links/[id]/transactions/sync?cursor=SOME_STRING_VALUE&size=SOME_INTEGER_VALUE")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer REPLACE_BEARER_TOKEN'

response = http.request(request)
puts response.read_body
import Foundation

let headers = ["Authorization": "Bearer REPLACE_BEARER_TOKEN"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.moneykit.com/links/[id]/transactions/sync?cursor=SOME_STRING_VALUE&size=SOME_INTEGER_VALUE")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse)
}
})

dataTask.resume()
Response
{
"transactions": {
"created": [
{
"transaction_id": "c7318ff7-257c-490e-8242-03a815b223b7",
"account_id": "acc_6Tef269B6ZArSVpYrxtjBV",
"amount": 384.05,
"type": "debit",
"currency": "USD",
"date": "2023-02-16T00:00:00",
"datetime": "2023-02-16T09:14:11",
"description": "Regina's Mulberry",
"raw_description": "Regina's Mulberry #1402 T48999-84",
"pending": true,
"enrichment": {
"category": {
"value": "food_and_drink",
"confidence": 99
},
"subcategory": {
"value": "coffee",
"confidence": 99
},
"merchant": {
"id": "a0822a4f-a59b-4fc9-a768-d880da5bd090",
"name": "Starbucks",
"logo": "https://example.com/starbucks.png",
"confidence": 99
},
"processor": {
"id": "a0822a4f-a59b-4fc9-a768-d880da5bd090",
"name": "Square",
"logo": "https://example.com/square.png",
"confidence": 99
},
"recurrence": {
"frequency": "monthly",
"next_predicted_date": "2024-08-03"
}
},
"original_id": string
}
],
"updated": [
{
"transaction_id": "c7318ff7-257c-490e-8242-03a815b223b7",
"account_id": "acc_6Tef269B6ZArSVpYrxtjBV",
"amount": 384.05,
"type": "debit",
"currency": "USD",
"date": "2023-02-16T00:00:00",
"datetime": "2023-02-16T09:14:11",
"description": "Regina's Mulberry",
"raw_description": "Regina's Mulberry #1402 T48999-84",
"pending": true,
"enrichment": {
"category": {
"value": "food_and_drink",
"confidence": 99
},
"subcategory": {
"value": "coffee",
"confidence": 99
},
"merchant": {
"id": "a0822a4f-a59b-4fc9-a768-d880da5bd090",
"name": "Starbucks",
"logo": "https://example.com/starbucks.png",
"confidence": 99
},
"processor": {
"id": "a0822a4f-a59b-4fc9-a768-d880da5bd090",
"name": "Square",
"logo": "https://example.com/square.png",
"confidence": 99
},
"recurrence": {
"frequency": "monthly",
"next_predicted_date": "2024-08-03"
}
},
"original_id": string
}
],
"removed": [
string
]
},
"accounts": [
{
"account_id": "acc_6Tef269B6ZArSVpYrxtjBV",
"account_type": "depository.checking",
"name": "Premier Checking",
"account_mask": "3748",
"balances": {
"currency": "USD",
"available": 340.12,
"current": 445.89,
"limit": 500,
"balance_date": "2021-08-12T15:23:00Z"
},
"original_id": null,
"closed": true
}
],
"cursor": {
"next": "c2FtcGxlIGN1cnNvcg=="
},
"has_more": true,
"link": {
"link_id": "mk_eqkWN34UEoa2NxyALG8pcV",
"institution_id": "chase",
"institution_name": "Chase",
"institution_avatar": "https://example.com/avatar.png",
"state": "connected",
"error_code": null,
"link_tags": [
"smoke_test",
"user_type:admin"
],
"webhook": "https://example.com/webhook",
"products": {
"accounts": {
"refreshed_at": "2023-02-16T09:14:11",
"last_attempted_at": "2023-02-16T09:14:11",
"error_code": "rate_limit",
"error_message": string,
"unavailable": string
},
"account_numbers": {
"refreshed_at": "2023-02-16T09:14:11",
"last_attempted_at": "2023-02-16T09:14:11",
"error_code": "rate_limit",
"error_message": string,
"unavailable": string
},
"identity": {
"refreshed_at": "2023-02-16T09:14:11",
"last_attempted_at": "2023-02-16T09:14:11",
"error_code": "rate_limit",
"error_message": string,
"unavailable": string
},
"transactions": {
"refreshed_at": "2023-02-16T09:14:11",
"last_attempted_at": "2023-02-16T09:14:11",
"error_code": "rate_limit",
"error_message": string,
"unavailable": string
},
"investments": {
"refreshed_at": "2023-02-16T09:14:11",
"last_attempted_at": "2023-02-16T09:14:11",
"error_code": "rate_limit",
"error_message": string,
"unavailable": string
},
"enrichment": {
"refreshed_at": "2023-02-16T09:14:11",
"last_attempted_at": "2023-02-16T09:14:11",
"error_code": "rate_limit",
"error_message": string,
"unavailable": string
}
},
"available_products": [
"account_numbers"
]
}
}
{
"error_code": "api_error.auth.expired_access_token",
"error_message": "Access token expired",
"documentation_url": string
}
{
"error_code": "link_error.forbidden_action",
"error_message": "Accounts access not permitted",
"documentation_url": string
}
{
"error_code": "link_error.not_found",
"error_message": "Link not found.",
"documentation_url": string
}
{
"error_code": "link_error.deleted",
"error_message": "This link was deleted at some earlier time.",
"documentation_url": string
}
{
"error_code": "link_error.bad_state",
"error_message": string,
"documentation_url": string,
"link_error_code": string
}
{
"error_code": "api_error.rate_limit_exceeded",
"error_message": "Rate limit exceeded",
"documentation_url": string
}

cursor

: string

A cursor value representing the last update requested. If included, the response will only return changes after this update. If omitted, a complete history of updates will be returned. This value must be stored by the client as we do not keep track of app cursors.

size

: integer

The number of items to return.

default: 50

id

: string

required

The unique ID for this link.

example: mk_eqkWN34UEoa2NxyALG8pcV

Responses

200

Successful Response

transactions

: object

Created, updated, and removed transactions. These lists are unordered.

accounts

: array

A list of accounts for which transactions are being returned.

cursor

: object

Pagination information

has_more

: boolean

This condition indicates the presence of transaction updates exceeding the requested count. If true, additional updates MUST be retrieved by making an additional request with cursor set to cursor.next.

403

Forbidden by link owner. The user did not give permission to access this data when linking.

error_code

: string

link_error.forbidden_action

default: "link_error.forbidden_action"

Allowed values:

"link_error.forbidden_action"

error_message

: string

Error message

example: Accounts access not permitted

documentation_url

: string

404

Link not found.

error_code

: string

link_error.not_found

default: "link_error.not_found"

Allowed values:

"link_error.not_found"

error_message

: string

default: "Link not found."

documentation_url

: string

410

Link deleted.

error_code

: string

link_error.deleted

default: "link_error.deleted"

Allowed values:

"link_error.deleted"

error_message

: string

default: "This link was deleted at some earlier time."

documentation_url

: string

422

Link error.

error_code

: string

link_error.bad_state

default: "link_error.bad_state"

Allowed values:

"link_error.bad_state"

error_message

: string

documentation_url

: string

429

Rate limit exceeded.

error_code

: string

api_error.rate_limit_exceeded

default: "api_error.rate_limit_exceeded"

Allowed values:

"api_error.rate_limit_exceeded"

error_message

: string

Error message

default: "Rate limit exceeded"

documentation_url

: string