Skip to main content

Find and Fetch Flexible Credentials

Overview

This page explains how to read a flexible credential and everything attached to it, including member cards, activity, and the events that record which credentials a transaction tried.

There is no root query for FlexibleCredential, so every read starts from an ID you already have. First find the credential from its own ID, a PaymentCard, a FinancialAccount, or an account holder. Then fetch the activity attached to it. Transactions carry their own record of which credentials were tried, so that read starts from the transaction instead.

Resolve the credential through node(id: ID!): Node with an inline fragment, or follow the reverse pointer from a card or account. For the object model, see How it's structured.

The connections on this page paginate on different objects, which changes how cursors behave. See Pagination.

Find a credential

Each starting point reaches the credential through a different field. PaymentCard and FinancialAccount each carry a flexibleCredential reverse pointer, which resolves to null when that card or account is not part of one. Refer to the examples just below.

Starting from IDUse node(id) onResulting field
FlexibleCredential IDFlexibleCredentialFlexibleCredential
PaymentCard IDPaymentCardFlexibleCredential or null
FinancialAccount IDFinancialAccountFlexibleCredential or null
USPersonAccountHolder, USBusinessAccountHolder, Business, or Organization IDUSPersonAccountHolderFlexibleCredentialConnection
From a Flexible Credential ID
query FlexibleCredentialById($id: ID!) {
node(id: $id) {
... on FlexibleCredential {
id
status
}
}
}

Full query and response: Find a credential by ID.

From a Payment Card ID
query FlexibleCredentialFromPaymentCard($id: ID!) {
node(id: $id) {
... on PaymentCard {
flexibleCredential {
id
}
}
}
}

Returns null when the card is not part of a flexible credential. Full query and response: Find the credential for a card.

From a Financial Account ID
query FlexibleCredentialFromFinancialAccount($id: ID!) {
node(id: $id) {
... on FinancialAccount {
flexibleCredential {
id
}
}
}
}

Returns null when the account does not back a member card. Full query and response: Find the credential for a financial account.

From an account holder ID
query FlexibleCredentialsForAccountHolder($id: ID!) {
node(id: $id) {
... on USPersonAccountHolder {
flexibleCredentials(first: 20) {
edges {
node {
id
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}

Full query and response: Find credentials for an account holder.

FlexibleCredential IDs are opaque strings you pass back to Highnote. See Entity IDs and Object Types.

Find a credential by ID

You can fetch a FlexibleCredential and unpack every member card on it, including the primary.

FlexibleCredentialByNode
Query
query FlexibleCredentialByNode($id: ID!) {
node(id: $id) {
... on FlexibleCredential {
id
externalId
name
status
createdAt
updatedAt
primaryPaymentCard {
id
last4
}
cards {
isPrimary
paymentCard {
id
last4
}
defaultFinancialAccount {
id
name
}
}
accountHolder {
... on USPersonAccountHolder {
id
}
... on USBusinessAccountHolder {
id
}
... on Business {
id
}
... on Organization {
id
}
}
cardProduct {
id
name
}
}
}
}
Variables
{
  "id": "FLEXIBLE_CREDENTIAL_ID"
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
Result
{
"data": {
"node": {
"id": "FLEXIBLE_CREDENTIAL_ID",
"externalId": "EXTERNAL_ID",
"name": "Cardholder Flexible Credential",
"status": "ACTIVE",
"createdAt": "2026-04-01T15:30:00.000Z",
"updatedAt": "2026-04-01T15:30:00.000Z",
"primaryPaymentCard": {
"id": "PAYMENT_CARD_ID_PRIMARY",
"last4": "4242"
},
"cards": [
{
"isPrimary": true,
"paymentCard": {
"id": "PAYMENT_CARD_ID_PRIMARY",
"last4": "4242"
},
"defaultFinancialAccount": {
"id": "FINANCIAL_ACCOUNT_ID_DEBIT",
"name": "Debit Account"
}
},
{
"isPrimary": false,
"paymentCard": {
"id": "PAYMENT_CARD_ID_SECONDARY",
"last4": "1881"
},
"defaultFinancialAccount": {
"id": "FINANCIAL_ACCOUNT_ID_CREDIT",
"name": "Revolving Credit Account"
}
}
],
"accountHolder": {
"id": "ACCOUNT_HOLDER_ID"
},
"cardProduct": {
"id": "CARD_PRODUCT_ID",
"name": "Flexible Credential Card Product"
}
}
}
}

Find the credential for a card

Given a PaymentCard ID, you can resolve its parent FlexibleCredential and list every sibling card on the credential. The result is null when the card is not part of a flexible credential.

FlexibleCredentialFromPaymentCard
Query
query FlexibleCredentialFromPaymentCard($id: ID!) {
node(id: $id) {
... on PaymentCard {
id
last4
flexibleCredential {
id
status
cards {
isPrimary
paymentCard {
id
last4
}
defaultFinancialAccount {
id
name
}
}
}
}
}
}
Variables
{
  "id": "PAYMENT_CARD_ID_PRIMARY"
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
Result
{
"data": {
"node": {
"id": "PAYMENT_CARD_ID_PRIMARY",
"last4": "4242",
"flexibleCredential": {
"id": "FLEXIBLE_CREDENTIAL_ID",
"status": "ACTIVE",
"cards": [
{
"isPrimary": true,
"paymentCard": {
"id": "PAYMENT_CARD_ID_PRIMARY",
"last4": "4242"
},
"defaultFinancialAccount": {
"id": "FINANCIAL_ACCOUNT_ID_DEBIT",
"name": "Debit Account"
}
},
{
"isPrimary": false,
"paymentCard": {
"id": "PAYMENT_CARD_ID_SECONDARY",
"last4": "1881"
},
"defaultFinancialAccount": {
"id": "FINANCIAL_ACCOUNT_ID_CREDIT",
"name": "Revolving Credit Account"
}
}
]
}
}
}
}

Find the credential for a financial account

Given a FinancialAccount ID, you can resolve the FlexibleCredential whose member card it backs, along with every card on that credential. The result is null when the account does not back a member card.

FlexibleCredentialFromFinancialAccount
Query
query FlexibleCredentialFromFinancialAccount($id: ID!) {
node(id: $id) {
... on FinancialAccount {
id
name
flexibleCredential {
id
status
cards {
isPrimary
paymentCard {
id
last4
}
defaultFinancialAccount {
id
name
}
}
}
}
}
}
Variables
{
  "id": "FINANCIAL_ACCOUNT_ID_DEBIT"
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
Result
{
"data": {
"node": {
"id": "FINANCIAL_ACCOUNT_ID_DEBIT",
"name": "Debit Account",
"flexibleCredential": {
"id": "FLEXIBLE_CREDENTIAL_ID",
"status": "ACTIVE",
"cards": [
{
"isPrimary": true,
"paymentCard": {
"id": "PAYMENT_CARD_ID_PRIMARY",
"last4": "4242"
},
"defaultFinancialAccount": {
"id": "FINANCIAL_ACCOUNT_ID_DEBIT",
"name": "Debit Account"
}
},
{
"isPrimary": false,
"paymentCard": {
"id": "PAYMENT_CARD_ID_SECONDARY",
"last4": "1881"
},
"defaultFinancialAccount": {
"id": "FINANCIAL_ACCOUNT_ID_CREDIT",
"name": "Revolving Credit Account"
}
}
]
}
}
}
}

Find credentials for an account holder

To find credentials for any account holder, the flexibleCredentials connection is exposed on Business, Organization, USBusinessAccountHolder, and USPersonAccountHolder. The page size is bounded by Highnote's standard pagination limit (1 to 20 items per page).

FlexibleCredentialsForAccountHolder
Query
query FlexibleCredentialsForAccountHolder(
$id: ID!
$first: Int! = 20
$after: String
) {
node(id: $id) {
... on USPersonAccountHolder {
id
flexibleCredentials(first: $first, after: $after) {
edges {
cursor
node {
id
name
status
primaryPaymentCard {
id
last4
}
}
}
pageInfo {
hasNextPage
endCursor
startCursor
}
}
}
}
}
Variables
{
  "id": "US_PERSON_ACCOUNT_HOLDER_ID",
  "first": 20
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
Result
{
"data": {
"node": {
"id": "US_PERSON_ACCOUNT_HOLDER_ID",
"flexibleCredentials": {
"edges": [
{
"cursor": "CURSOR_1",
"node": {
"id": "FLEXIBLE_CREDENTIAL_ID",
"name": "Cardholder Flexible Credential",
"status": "ACTIVE",
"primaryPaymentCard": {
"id": "PAYMENT_CARD_ID_PRIMARY",
"last4": "4242"
}
}
}
],
"pageInfo": {
"hasNextPage": false,
"endCursor": "CURSOR_1",
"startCursor": "CURSOR_1"
}
}
}
}
}

Fetch what the credential holds

Once you have the credential, you can retrieve the activity of its member accounts.

Fetch activity across credentials

flexibleCredentialActivities answers what is happening across the credential now. It returns the activity of every member financial account as a single, chronologically ordered feed, so you do not have to fetch each credential's account separately and interleave the results yourself. Each row carries sourceFinancialAccount, which attributes it to the credential it came from.

FlexibleCredentialActivities
Query
query FlexibleCredentialActivities(
$id: ID!
$first: Int! = 20
$after: String
) {
node(id: $id) {
... on FlexibleCredential {
id
flexibleCredentialActivities(first: $first, after: $after) {
edges {
cursor
node {
sourceFinancialAccount {
id
name
}
activity {
createdAt
sign
isComplete
pendingAmount {
value
currencyCode
}
postedAmount {
value
currencyCode
}
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
Variables
{
  "id": "FLEXIBLE_CREDENTIAL_ID",
  "first": 20
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
Result
{
"data": {
"node": {
"id": "FLEXIBLE_CREDENTIAL_ID",
"flexibleCredentialActivities": {
"edges": [
{
"cursor": "CURSOR_1",
"node": {
"sourceFinancialAccount": {
"id": "FINANCIAL_ACCOUNT_ID_CREDIT",
"name": "Revolving Credit Account"
},
"activity": {
"createdAt": "2026-04-01T15:30:00.000Z",
"sign": "NEGATIVE",
"isComplete": false,
"pendingAmount": {
"value": 3500,
"currencyCode": "USD"
},
"postedAmount": null
}
}
},
{
"cursor": "CURSOR_2",
"node": {
"sourceFinancialAccount": {
"id": "FINANCIAL_ACCOUNT_ID_DEBIT",
"name": "Debit Account"
},
"activity": {
"createdAt": "2026-03-30T09:12:00.000Z",
"sign": "NEGATIVE",
"isComplete": true,
"pendingAmount": null,
"postedAmount": {
"value": 1250,
"currencyCode": "USD"
}
}
}
}
],
"pageInfo": {
"hasNextPage": false,
"endCursor": "CURSOR_2"
}
}
}
}
}

This connection is aggregated at the flexible credential, so its cursors span the whole feed and after pages through all credentials together.

Trace a transaction's routing

This read starts from a transaction rather than a credential.

Find attempt events on a transaction

Highnote records a FlexibleCredentialAttemptEvent on the transaction for each credential that is tried and declines. Every transaction also carries exactly one AuthorizationEvent, which holds the final outcome on the last credential tried, whether that credential approved or declined. This is how you reconstruct, after the fact, which credentials were tried and how each one responded.

no attempt events

A credential that is never tried produces no attempt event. Transactions restricted to the primary credential drop the secondaries before selection runs, and a card verification failure skips selection entirely.

Filter a transaction's events with FLEXIBLE_CREDENTIAL_ATTEMPT_EVENT to read them. Requesting AUTHORIZATION_EVENT in the same call gives you the full picture: every credential that declined, plus the final outcome.

FlexibleCredentialAttempts
Query
query FlexibleCredentialAttempts($id: ID!) {
node(id: $id) {
... on DebitTransaction {
id
transactionEvents(
eventTypes: [FLEXIBLE_CREDENTIAL_ATTEMPT_EVENT, AUTHORIZATION_EVENT]
) {
__typename
... on FlexibleCredentialAttemptEvent {
id
createdAt
responseCode
requestedAmount {
value
currencyCode
}
paymentCard {
id
last4
}
spendRuleResults(first: 20) {
edges {
node {
recommendation
message
attachedLevel
}
}
}
}
... on AuthorizationEvent {
id
createdAt
responseCode
approvedAmount {
value
currencyCode
}
paymentCard {
id
last4
}
}
}
}
}
}
Variables
{
  "id": "DEBIT_TRANSACTION_ID"
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
Result
{
"data": {
"node": {
"id": "DEBIT_TRANSACTION_ID",
"transactionEvents": [
{
"__typename": "FlexibleCredentialAttemptEvent",
"id": "FLEXIBLE_CREDENTIAL_ATTEMPT_EVENT_ID",
"createdAt": "2026-04-01T15:30:00.000Z",
"responseCode": "DO_NOT_HONOR",
"requestedAmount": {
"value": 3500,
"currencyCode": "USD"
},
"paymentCard": {
"id": "PAYMENT_CARD_ID_SECONDARY",
"last4": "1881"
},
"spendRuleResults": {
"edges": [
{
"node": {
"recommendation": "BLOCK",
"message": "Merchant category not permitted on this account",
"attachedLevel": "ACCOUNT"
}
}
]
}
},
{
"__typename": "AuthorizationEvent",
"id": "AUTHORIZATION_EVENT_ID",
"createdAt": "2026-04-01T15:30:00.100Z",
"responseCode": "APPROVED",
"approvedAmount": {
"value": 3500,
"currencyCode": "USD"
},
"paymentCard": {
"id": "PAYMENT_CARD_ID_PRIMARY",
"last4": "4242"
}
}
]
}
}
}

The paymentCard object identifies which credential the attempt ran against, and responseCode gives the decline reason. When a spend rule caused the fallback, spendRuleResults names the rule that produced it. It is the observable counterpart to credential selection, where a decline for any reason moves to the next credential.

Attempt events do not settle. They share the approved event's transaction, so they show up as part of that transaction's history rather than as transactions of their own.

Pagination

The two connections on this page paginate on different objects.

ConnectionPaginates onA cursor is valid for
flexibleCredentialsthe account holderthat account holder's list
flexibleCredentialActivitiesthe flexible credentialthe whole combined feed

The mechanics are the same in every case. Request up to 20 items with first, pass the previous page's endCursor as after, and check pageInfo.hasNextPage to know when to stop.

What differs is the scope of the cursor, which is why a cursor from one account holder's list cannot be used against the combined activity feed.