Utilities for inspecting and managing Tink.Client access token state.
Complements Tink.Auth by providing helpers to check expiry, extract
scopes, and decide whether a token needs refreshing — without making
any API calls.
Example
{:ok, client} = Tink.Auth.client_credentials(scope: "accounts:read transactions:read")
Tink.AuthToken.expired?(client)
# => false
Tink.AuthToken.scopes(client)
# => ["accounts:read", "transactions:read"]
Tink.AuthToken.has_scope?(client, "transactions:read")
# => true
Tink.AuthToken.has_scope?(client, "payment:write")
# => false
Tink.AuthToken.seconds_until_expiry(client)
# => 3542
Tink.AuthToken.should_refresh?(client)
# => false (becomes true when < 5 min remain)
Summary
Functions
Returns true if the token has expired.
Returns a human-readable expiry string, e.g. "expires in 59 min",
"expired 2 min ago", or "no expiry".
Returns true if the token has all of the given scopes.
Returns true if the token has the given scope.
Returns the list of scopes from required_scopes that are missing from
the token. Returns an empty list when all scopes are present.
Returns the list of scopes granted to this token. Returns an empty list if no scope is set.
Returns the number of seconds until the token expires.
Returns nil when no expiry is set (token lives forever).
Returns 0 or a negative number when already expired.
Returns true when the token is within the refresh threshold (default 5 min)
or has already expired.
Returns a summary map for logging/debugging. Does NOT include the access token.
Functions
@spec expired?(Tink.Client.t()) :: boolean()
Returns true if the token has expired.
@spec expiry_summary(Tink.Client.t()) :: String.t()
Returns a human-readable expiry string, e.g. "expires in 59 min",
"expired 2 min ago", or "no expiry".
@spec has_all_scopes?(Tink.Client.t(), [String.t()]) :: boolean()
Returns true if the token has all of the given scopes.
Example
Tink.AuthToken.has_all_scopes?(client, ["accounts:read", "transactions:read"])
# => true
@spec has_scope?(Tink.Client.t(), String.t()) :: boolean()
Returns true if the token has the given scope.
Handles both space-separated and comma-separated scope strings.
Example
Tink.AuthToken.has_scope?(client, "transactions:read")
# => true
@spec missing_scopes(Tink.Client.t(), [String.t()]) :: [String.t()]
Returns the list of scopes from required_scopes that are missing from
the token. Returns an empty list when all scopes are present.
Example
Tink.AuthToken.missing_scopes(client, ["accounts:read", "payment:write"])
# => ["payment:write"]
@spec scopes(Tink.Client.t()) :: [String.t()]
Returns the list of scopes granted to this token. Returns an empty list if no scope is set.
@spec seconds_until_expiry(Tink.Client.t()) :: integer() | nil
Returns the number of seconds until the token expires.
Returns nil when no expiry is set (token lives forever).
Returns 0 or a negative number when already expired.
@spec should_refresh?( Tink.Client.t(), keyword() ) :: boolean()
Returns true when the token is within the refresh threshold (default 5 min)
or has already expired.
Use this to proactively refresh tokens before they expire mid-request:
if Tink.AuthToken.should_refresh?(client) do
{:ok, client} = Tink.Auth.client_credentials(scope: client.scope)
endOptions
:threshold_seconds— seconds before expiry to consider stale (default: 300)
@spec summary(Tink.Client.t()) :: %{ expired: boolean(), expiry: String.t(), scope_count: non_neg_integer(), scopes: [String.t()], auto_refresh: boolean(), cache: boolean() }
Returns a summary map for logging/debugging. Does NOT include the access token.
Example
Tink.AuthToken.summary(client)
# => %{
# expired: false,
# expiry: "expires in 59 min",
# scope_count: 3,
# scopes: ["accounts:read", "transactions:read", "balances:read"],
# auto_refresh: false,
# cache: true
# }