Caller credentials
A caller-bound integration can run an API call as your end user, with a bearer token or named secret fields you supply on the request, instead of the credential stored in Yekar.AI for your organization. Your API's own authorization is the ceiling either way; Yekar.AI never widens it.
callerCredentials is optional on /triggers/fire, both personal-key Agent message routes, and the console's turn-approval route. On a conversation, credentials are forwarded to the target, narrowed to the integrations it binds at caller identity, and limited to the turn that supplied them. An agent or flow that requires a credential you did not send fails rather than quietly running as your organization.
The outer object and every per-integration entry are strict objects. Unknown keys are rejected rather than stripped.
| Field | Type | Required | Notes |
|---|---|---|---|
callerCredentials.integrations | object | Yes when callerCredentials is present | Map keyed by integration id. Integration ids must be 1–64 characters. |
integrations.<id>.token | string | No | Bearer token, 1–8,192 characters with no newline. Its format is not otherwise interpreted. |
integrations.<id>.fields | object | No | One to 16 named secrets. Keys are 1–64 ASCII letters, numbers, or _; values have the same bounds as token. |
integrations.<id>.fallbackAllowed | boolean | No | Defaults to true. Set false to require caller authority for this call. |
token and fields may coexist. Which channel an integration prefers is defined by that integration. Caller fields replace stored secret material rather than merging with it; a partial caller credential does not silently borrow the missing half from the organization's credential. Field names that the selected integration does not declare are removed before invocation, so verify names against that integration's contract.
{
"triggerId": "9f21ab04-…",
"input": { "accountRef": "ACME-4471" },
"callerCredentials": {
"integrations": {
"yekar.http": { "token": "eyJhbGciOi…" },
"yekar.wordpress": {
"fields": {
"USERNAME": "end-user",
"APPLICATION_PASSWORD": "application-password"
}
}
}
}
}
It is a map, not one token for the whole agent or flow. Even when one token covers several integrations, repeat it under each integration id. Otherwise adding an integration later would silently widen where that token can flow.
Who does the call run as?
Two choices decide this, and the stricter one wins. The agent or flow's author sets the binding policy. Prefer caller uses caller material when supplied and otherwise permits the organization's connected credential. Caller required always requires caller material and cannot be relaxed by a fire request.
The request supplies the second choice per integration. Leave fallbackAllowed at its default true to permit the organization's credential when no caller material is present. Set it to false to require caller material for that execution. A credential you actually send is used as the caller. With no supplied credential, execution fails if either side required the caller; otherwise it uses the organization's credential.
An empty entry {} is valid and behaves like omission. fields: {} is invalid because it asserts a fields credential while supplying no fields. An entry containing only fallbackAllowed: false is a valid strictness declaration - and will fail if no credential is supplied.
Is the credential stored?
Yekar.AI encrypts caller material at rest and holds it for the execution's lifetime unless callerCredentialExpiresAt declares an earlier ISO-8601 expiry. The provider judges validity when the integration is used. Settled execution paths delete grants; the worker sweep sheds ciphertext after declared expiry or execution termination. A later execution cannot reuse the prior grant.
The selected integration necessarily receives the decrypted material when it is invoked. Its behavior is outside this custody boundary: Yekar.AI cannot guarantee that an integration or vendor will not echo a credential in its output or an error. Scope credentials for one call, and do not send a broad session token.
The one-hour window limits Yekar.AI's custody; it does not narrow the credential's own permissions. If an upstream service rejects supplied caller material, Yekar.AI does not retry the operation with the organization's stored authority.
Two credentials, two audiences
The Authorization header authenticates you to Yekar.AI. callerCredentials authenticates your end user to the integration keyed by that entry. Your API key is never sent upstream, and caller material is never sent to an integration it was not keyed for.
curl -X POST "https://api.yekar.ai/api/v1/triggers/fire" \
-H "Authorization: Bearer $YEKAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"triggerId": "9f21ab04-…",
"input": { "accountRef": "ACME-4471" },
"callerCredentials": {
"integrations": {
"yekar.http": { "token": "'"$END_USER_TOKEN"'" }
}
}
}'
Where caller-required integrations can run
A caller-required integration needs an entry path that can carry end-user material. /triggers/fire and the personal-key Agent message routes can. The product's Run and Test run buttons cannot - they have no end user to ask - so they refuse the field rather than run under organization authority by default.
An agent or flow with a caller-required binding may subscribe to a trigger. Whether it can actually run then depends on how that trigger fires:
| Firing | Result |
|---|---|
POST /api/v1/triggers/fire | Runs, using the credentials on the request. Each subscriber receives only the integrations it binds at caller identity. |
| Schedule | Refused. A scheduled firing has no caller, so nothing can supply the required material. |
| Event | Refused, for the same reason. |
A refused subscriber reports CALLER_CREDENTIALS_REQUIRED in the trigger's Run history and does not stop the others: a firing whose subscribers disagree is recorded as partial. Credentials that no subscriber used are recorded as supplied-but-unused integration ids; material is never written to history.
If work reaches caller material after its declared expiry, it fails with CALLER_CREDENTIAL_EXPIRED instead of falling back to organization authority. Provider-rejected material remains an ordinary integration failure.
Resuming after approval
A caller grant is retained while a turn waits for tool approval, but its declared expiry and the execution deadline still apply. If it expires while the turn is suspended, approving without replacement credentials resumes the gated call as a failed tool result with CALLER_CREDENTIAL_EXPIRED; it does not fall back to organization identity and does not crash the turn worker.
Both the cookie-authenticated console route POST /sessions/:id/turn-approval and the personal-key route POST /api/v1/agents/sessions/:sessionId/turn-approval accept the same optional callerCredentials object alongside decision, approvalId, and comment. The Agent API stream exposes the id as approvalId on turn.suspended and as pendingApprovalId in its snapshot. On approval, supplied credentials replace the expired grant for the parked execution. A short-lived yku_ can therefore be supplied as the caller credential for the relevant integration without changing the route's own yk_ authentication. The replacement remains scoped to that execution and is deleted when the turn settles.