Integrated accounts Object
Properties
Type of authentication used.
oauth2api_keyoauth2_client_credentialskeka_oauth
The context of the integrated account. You can find these in the Variables section of an integrated account in the Truto UI.
{"zendesk_subdomain":"truto"}The date and time when the integrated account was created.
2021-08-10T10:00:00.000ZThe ID of the environment integration (installed integration).
b179ad55-db02-4bd4-b7a4-d2c173eee9aeThe ID of the integrated account.
1ba1f401-7183-47c5-9e39-e8e257e3c795Whether the integrated account is in sandbox mode or not. Sandbox integrated accounts do not allow any "write" operations.
falseThe results of the post install and validation steps that ran on the integrated account.
The last error that occurred while running the post install or validation steps.
Details of the most recent 403 Forbidden returned by the third-party API for this
account, or null if the most recent call succeeded. Cleared automatically on the next
successful call.
The sentence the live 403 carried, recorded so this row reads the same as the call did.
Access forbidden. This operation requires a role or privilege granted in the provider's own admin console, not an OAuth scope — reconnecting will not change it.The method that was attempted on that resource.
listScopes of which the operation needs any one, where the grant holds none. Kept
apart from missing_scopes so alternatives are never reported as though all were
required.
["Chat.Read.All","Chat.ReadWrite.All"]The scopes required by this resource and method that the provider did not confirm as granted.
Present only when both halves of that comparison are known: the provider echoed the
scopes it granted, and this resource and method declares required scopes. It is
absent — not empty — otherwise, which includes api_key and OAuth1 connections
(no scope grant exists), OAuth2 and jwt_bearer connections where the provider
omits scope from its token response, resources and methods that declare no
required scopes, and requirements that are not OAuth scopes at all
(refusal_basis: non_scope_requirement — see permission_vocabulary), where no
diff is run and required_permissions carries the answer instead.
An empty array therefore means "no all-of scope is missing", while an absent
field means "cannot be determined" — two different statements. Read refusal_basis
for the one question this field cannot answer on its own, "was anything missing at
all": an empty array sits beside a populated missing_any_of_scopes whenever the
whole shortfall is an unmet any-of requirement, so on
refusal_basis: scopes_missing an empty array does not mean every permission
was granted. It means that on refusal_basis: scopes_satisfied, and only there. Do
not default an absent missing_scopes to [] either: that reads back as "nothing
is missing" about a request that was refused.
Truto's comparison is an inference over integration configuration. The provider's
own account of the refusal is the authoritative one, and Truto relays it without
interpreting it: raw_response (the error body verbatim) and message (its human
text) on the 403 itself, and a capped copy of the body on this record as
raw_response_excerpt. message is not persisted, so re-run the call to see it.
Truto deliberately does not lift a "code" or a "documentation link" out of that body. Which key in an arbitrary provider's error shape is the important one has no correct general answer, and a confidently wrong one placed above a correct body is the same failure as reporting a scope missing that was never checked.
["crm.objects.contacts.read"]When the forbidden response was recorded.
2021-08-10T10:00:00.000ZWhich vocabulary required_permissions is written in, and therefore what the
remedy is. Only oauth_scope is fixed by reconnecting: api_key_permission is
granted to the API key in the provider, and role_label in the provider's own
admin console.
x-extensible-enum for the same reason as refusal_basis above: this is a stored
value, and a rollback can serve one written by a build that knew a fourth
vocabulary. Keep a default branch.
role_labelA capped copy of the integration's own error body, so this record shows what the
provider said and not only what Truto inferred about it. Truncated with a trailing
… truncated marker past 2,048 bytes of UTF-8, because this record is
deserialized on every proxy and unified call that resolves the account and that cost
is what the bound exists to control. Bytes, not characters: 2,048 characters of CJK
is about 6 KB stored, so a character bound would charge one language three times
what it charges another. Expect fewer characters than 2,048 for any non-ASCII body.
The 2,048 covers the marker as well, so the stored value never exceeds it.
A truncated excerpt is not parseable. It is a byte prefix of a serialized body
with a marker on the end, so JSON.parse on this field throws whenever truncation
happened — which the trailing … truncated is how you detect. Render it as text.
An untruncated excerpt of a JSON body does parse, but nothing guarantees this field
is JSON at all: a plain-text or HTML error body is stored exactly as it arrived.
Absent when the refusal carried no body. Not forwarded to the connections widget:
it is a raw provider string, which is what connections.show_error_details exists
to keep away from an end user.
Note that "every remote 403 carries an insight" and "every remote 403 leaves a
record here" are different statements. A Proxy API custom method and a Custom
API both carry the live insight, but a Custom API names no resource or method, and
writing {resource: "", method: ""} would replace a record naming a real call with
one naming none — so no record is written for those. Read the insight on the
response for them.
{"error":"insufficient_scope","error_description":"Token does not have crm.objects.contacts.write scope"}Which of the states below produced this record, so a reader never has to infer it
from the presence or emptiness of missing_scopes. Absent on rows recorded before
Truto stored it — and on such a row an empty missing_scopes cannot be read as
"compared, nothing missing", because it was also written when nothing had been
compared at all.
An open set, and x-extensible-enum rather than enum says so to a code
generator as well as to a reader. Prose asking for a default branch is not
something a generator reads, and a closed union here can be violated by design:
the read path deliberately accepts an unrecognised value so a row written by a
newer build stays readable after a rollback, and the older build then serves that
value straight back on this field. The values below are what Truto writes today.
Keep a default branch.
The live truto_error_insight.forbidden_error.value.refusal_basis keeps a closed
enum, and the asymmetry is the point: a running build always emits its own
documented set, while a stored row can carry a value the build reading it never
wrote.
non_scope_requirementPermissions of which the operation needs any one, kept apart from required_permissions for the same reason.
["Chat.Read.All"]What this operation requires, whether or not a comparison was possible. Always
paired with permission_vocabulary, since the same string means "reconnect and
grant this", "add this to your API key" or "ask an admin for this role" depending
on which vocabulary it is written in.
["Agent","Customers Read"]The third-party resource that was forbidden.
contactsThe region where the integrated account is placed.
wnamwnamenamapaceu
Status of the integrated account.
active- Everything is fine and the account should workconnecting- Post install and validation steps are being runpost_install_error- There was an error while running post install stepsvalidation_error- There was an error while running validation stepsneeds_reauth- There was an error while refreshing the credentials in case of OAuth authentication or the credentials are no longer valid in other authentication methods. The integrated account needs to be reauthorized.
activeconnectingpost_install_errorvalidation_errorneeds_reauth
The ID of the tenant.
acme-1The date and time when the integrated account was last updated.
2021-08-10T10:00:00.000Z