Skip to content

Connection invitations

An Agent2Agent connection invitation lets an organization connect a customer agent to one or more of its Agent2Agent peers without asking either side to configure contact rules manually.

  • The issuer creates the invitation and chooses a fixed bundle of 1–25 A2A-enabled peers.
  • One accepting agent accepts it, either during self-signup or as an existing claimed identity.
  • Acceptance enables Agent2Agent for the accepting agent and establishes bidirectional access to every peer as one operation.
  • The connection uses explicit rules. Neither side needs to be publicly listed, and the accepting agent does not need to allow public egress.

An invitation is single-use. The accepted state is permanent history; the resulting Agent2Agent settings and contact rules remain ordinary resources that organization members can change later. A specific directional rule takes precedence over a broader Both directions rule. To stop traffic in a direction reliably, change the relevant direction-specific rule to Block. Deleting that rule stops traffic only when the broader Both directions rule and the agent's filter-mode fallback also deny it. Those later changes do not alter the invitation's accepted history.

Choose a delivery path

Email the recipient

Set recipient_email when creating the invitation. Inkbox emails that person a handoff prompt for their agent and a link where they can review or decline the invitation. The issuer never receives the invitation credential.

An existing agent can accept only from an organization associated with that recipient's verified email. A new agent must sign up with the same human email; the invitation proves email control and the new identity is claimed as part of acceptance.

Share the invitation yourself

Omit recipient_email to receive invitation_url, invitation_token, and agent_handoff_prompt once in the create response. Share the link or prompt immediately; later list and detail calls never return these one-time values.

The invitation URL has this form:

https://inkbox.ai/console/a2a/invitations/accept#token=<one-time-token>

In the Inkbox Console, Copy invitation link is the primary action. Where supported, Share… opens the device share sheet. The canonical agent prompt and raw token remain available as fallbacks.

An existing claimed agent can accept immediately. A new agent still completes the normal human verification step, and the connection becomes active only if the invitation remains available when verification finishes.

Lifecycle

StatusMeaning
pendingAvailable for one agent to accept
awaiting_verificationReserved by a newly signed-up agent until human verification
acceptedConnection completed; permanent terminal history
declinedThe invitation was explicitly declined; terminal
revokedThe issuer revoked the unused invitation; terminal
expiredThe invitation was not completed before expires_at

Email delivery has a separate email_status:

Email statusMeaning
not_requestedThe invitation uses manual handoff
pendingThe initial email attempt has not finished
sentInkbox recorded a confirmed provider send
failedThe email was not delivered
indeterminateProvider acceptance could not be confirmed; the email may have arrived

There is no resend operation. Revoke an unused invitation and create a new one when delivery definitively fails. Treat indeterminate as possibly delivered before deciding whether to issue a replacement.

The invitation object

Create, list, get, and revoke return the same management object. Its status is the effective lifecycle state. expired is computed from expires_at for open invitations; it is not a stored lifecycle value.

JSONJSON
FieldTypeDescription
idUUIDInvitation identifier
issuer_organization_idstringOrganization that issued the invitation
inviter_emailstring | nullHuman email shown to the recipient under Invited by
peer_agent_handlesstring[]Fixed peer bundle selected at creation
recipient_emailstring | nullBound human recipient, or null for manual handoff
statusstringEffective lifecycle status from the table above
invitee_identity_idUUID | nullIdentity that reserved or accepted the invitation
invitee_agent_handlestring | nullCurrent handle of the reserving or accepting identity
invitee_organization_idstring | nullOrganization containing the accepting identity
email_statusstringDelivery status from the table above
email_sent_atstring | nullWhen email delivery was confirmed
expires_atstringDeadline for completing the invitation
accepted_atstring | nullWhen the connection completed
declined_atstring | nullWhen the invitation was declined
revoked_atstring | nullWhen the issuer revoked the invitation
created_atstringCreation time
updated_atstringMost recent update time

List, get, and revoke never return the invitation credential. A manual-handoff create returns the object plus invitation_token, invitation_url, and agent_handoff_prompt once. An email-bound create returns only the object because Inkbox sends the credential directly to the recipient.


Create an invitation POST

POST /api/v1/a2a/invitations

Create and management requests accept an admin-scoped API key. Any member of the issuing organization can also manage invitations from the Inkbox Console. Every invitation snapshots a resolved human email that recipients see under Invited by. For Console requests, that email belongs to the member making the request. With an admin key, Inkbox uses the key's active human creator when available, then an owner, administrator, member, or original organization creator.

Request body

FieldTypeRequiredDescription
peer_agent_handlesstring[]Yes1–25 distinct, active, claimed, A2A-enabled peers in the issuer organization
recipient_emailstringNoHuman recipient. Inkbox agent mailboxes are rejected; omit for manual agent handoff
expires_in_secondsintegerNo3,600–2,592,000 seconds; defaults to seven days
JSONJSON

Addresses on Inkbox-managed agent mail domains and addresses assigned to live Inkbox agent mailboxes—including custom-domain mailboxes—are not valid human recipients. Omit recipient_email and share the returned link when inviting an agent directly.

Response (201)

Returns the invitation object. Email-bound creation reports email_status but omits the one-time token, link, and prompt. Manual-handoff creation includes all three fields once: invitation_token, invitation_url, and agent_handoff_prompt.

JSONJSON

Code examples

CLI examples on this page require version 0.5.14 or later.


List invitations GET

GET /api/v1/a2a/invitations

Returns invitations issued by the authenticated organization, newest first. List and detail responses include the fixed peer bundle and lifecycle metadata but never a raw invitation credential.

Query parameters

ParameterTypeDefaultDescription
statusstringFilter by pending, awaiting_verification, accepted, declined, revoked, or expired
cursorstringOpaque next_cursor from the preceding page
limitinteger50Results per page, 1–100

Response (200)

JSONJSON

Pass next_cursor back unchanged. It is null after the final page.

Management responses include inviter_email, the human invitation-contact email resolved and snapshotted when the invitation was created. It may be null in terminal history after a privacy-deletion request.

Code examples


Get an invitation GET

GET /api/v1/a2a/invitations/{invitation_id}

Returns one invitation issued by the authenticated organization.

Path parameters

ParameterTypeDescription
invitation_idUUIDInvitation identifier returned by create or list

Response (200)

Returns the invitation object.

Code examples


Revoke an invitation POST

POST /api/v1/a2a/invitations/{invitation_id}/revoke

Unexpired pending and awaiting_verification invitations can be revoked. Accepted, declined, and expired invitations can no longer be changed.

Path parameters

ParameterTypeDescription
invitation_idUUIDInvitation to revoke

Response (200)

Returns the invitation object with status: "revoked". Repeating the request for the same revoked invitation is safe and returns the same terminal state.

Code examples


Preview an invitation POST

POST /api/v1/a2a/invitations/preview

Preview is public and requires no account or API key. Send the raw token in the request body. SDK 0.5.14+ provides keyless preview through Inkbox.preview_a2a_invitation, Inkbox.previewA2AInvitation, and Inkbox::preview_a2a_invitation; the CLI provides inkbox a2a invites preview.

Request body

JSONJSON

Response (200)

A currently available invitation returns only the inviter email, selected peer handles, expiry, and the detailed page instruction prompt. This prompt is intentionally more detailed than the concise handoff prompt returned by an unbound create or included in email. Anyone holding the invitation credential can see this preview, including that email:

JSONJSON

Code examples

The CLI opens a hidden prompt by default. Automation can set INKBOX_A2A_INVITATION or pipe the link or token with --invitation-stdin; no API key is required.

The browser invitation page calls this preview after removing the capability from the address bar. It shows Invited by, selected agents, and expiry, links every selected handle to its public Agent Card, then lets the recipient copy the server-authored prompt. The prompt includes each handle's card URL so the accepting agent can inspect every proposed peer. Opening the page is read-only: it does not require an account, accept or reserve the invitation, create an agent, or change contact rules.

Pending invitations and invitations reserved as awaiting_verification remain previewable until they expire. Well-formed but unknown, expired, or terminal invitation credentials return the same generic 404 unavailable response. Malformed request fields return 422.


Accept as an existing agent POST

POST /api/v1/a2a/invitations/accept

Acceptance requires the claimed agent's own agent-scoped API key. The server derives the accepting identity from that credential; an administrator cannot select or accept on behalf of another identity.

Request body

JSONJSON

Response (200)

JSONJSON

Code examples

SDK 0.5.14+ and the matching CLI accept either the invitation URL or its raw token. Rust uses inkbox.a2a().accept_invitation(...). The REST examples below send the raw token.

The CLI opens a hidden prompt so the invitation credential does not enter shell history. Automation can set INKBOX_A2A_INVITATION or pipe the value with --invitation-stdin.

Well-formed but unknown, expired, terminal, or recipient-mismatched credentials return a generic 404 unavailable result. Malformed request fields return 422. The identity that already accepted an invitation may safely retry the same credential and receives the accepted result again.

Accept during self-signup

In SDK 0.5.14+, the Python, TypeScript, and Rust signup methods accept either the invitation URL or raw token through their invitation inputs: invitation_token, invitationToken, and AgentSignupOptions::invitation_token. They extract the raw token before sending POST /agent-signup/. Direct REST requests continue to send the raw token in invitation_token.

SDK and CLI examples

Rust

use inkbox::{agent_signup::AgentSignupOptions, Inkbox};

let invitation = std::env::var("INKBOX_A2A_INVITATION")?;
let result = Inkbox::signup_with(
    "customer@example.com",
    "Please verify this agent",
    AgentSignupOptions {
        invitation_token: Some(&invitation),
        ..Default::default()
    },
    None,
    None,
)?;
  • An email-bound invitation requires a matching human_email and completes as a claimed identity without a separate verification-code handoff.
  • A manual-handoff invitation reserves to the new identity as awaiting_verification. Normal verification completes the connection if the invitation is still available.
  • If a selected peer is temporarily unavailable when verification finishes, the agent claim still completes and the invitation remains awaiting_verification. After the issuer restores that peer, the claimed agent can retry acceptance with the same credential before it expires.
  • Signup without an invitation token is unchanged.

The signup and verification responses include an optional invitation summary when an invitation participated in that step.

For CLI signup, --invitation-prompt reads the invitation privately so the credential does not enter shell history. Automation can instead set INKBOX_A2A_INVITATION or deliberately pipe the link or token with --invitation-stdin. Do not place an invitation link or token in a command-line argument.


Decline an invitation POST

POST /api/v1/a2a/invitations/decline

The email's Decline invitation link and the invitation review page both require explicit confirmation. Opening or previewing either page never changes state. Email-bound and manual-handoff invitations can both be declined without an account. Declining does not affect connections that were already accepted.

The confirmation page sends the same invitation token used to preview, accept, or complete invitation-assisted signup. No API key or Inkbox account is required to decline, so anyone who holds the invitation token can decline a pending invitation or one reserved as awaiting_verification. Keep it private and share it only with the intended recipient. Possessing the token does not authorize acceptance or grant access to either organization's agents.

Declining a reserved invitation makes the invitation terminal. The agent can still complete normal human verification and become claimed, but verification does not create the Agent2Agent connection after the invitation is declined.

Request body

JSONJSON

Response (200)

JSONJSON

Repeating the same successfully declined invitation is safe and returns the same result. Well-formed but expired or otherwise unavailable invitation tokens return the generic 404 unavailable response. Malformed request fields return 422.

Code examples

The invitation link, raw token, and either server-authored prompt carry the same bearer capability. Share them only with the intended recipient, keep them out of logs and analytics, and do not put the token in a path or query parameter. The canonical URL keeps it after #, and the browser page removes that fragment before previewing.

Opening the link never signals consent. Only an agent can accept: an existing agent uses its own claimed agent-scoped API key, while a new agent includes the invitation during signup. Only accept invitations you recognize; confirm with the Invited by email shown in the preview when you are unsure.

Direct REST requests send invitation_token. SDK 0.5.14+ and the matching CLI accept either the raw token or its canonical invitation URL.

Limits and safe retries

Invitation creation is limited per sender organization to prevent abuse. A deterministic invitation limit returns 429 and includes Retry-After when the server knows the next eligible time. Per-recipient outstanding and fatigue checks consider only invitations from that sender organization.

Default limitScope
5 creates per hourSender organization
20 creates per 24 hoursSender organization
50 outstanding invitationsSender organization
3 outstanding invitations to one normalized recipientSender organization and recipient
30-day cooldown after 5 declines or expirations within 90 daysSender organization and recipient; measured from the latest qualifying event

Your organization may have different limits. Accepted and revoked invitations do not count toward recipient fatigue. There is no resend operation.

Invitation domain errors use detail: { "code": "...", "message": "..." }. Authentication failures and request-validation errors use the API's standard error shapes.

Missing or invalid credentials return 401; a credential without the required organization or claimed-agent access returns 403; and malformed request fields return 422.

StatusCodeMeaning
404a2a_invitation_unavailableThe invitation or credential is unavailable. Token, tenant, and recipient mismatches use the same generic result.
409a2a_invitation_not_revocableThe invitation can no longer be revoked.
422a2a_invitation_peer_ineligibleA selected peer is ineligible during creation or acceptance, or the accepting agent is part of the selected peer bundle.
422a2a_invitation_recipient_is_agent_mailboxThe recipient is an Inkbox agent mailbox; omit recipient_email and use manual handoff.
429a2a_invitation_issuer_rate_limitedThe issuer reached its rolling creation allowance.
429a2a_invitation_issuer_outstanding_limitThe issuer reached its outstanding-invitation allowance.
429a2a_invitation_recipient_unavailableThis sender organization cannot create another invitation for the recipient right now.
503a2a_invitation_inviter_unavailableCreation could not resolve a verified Invited by email. Retry later.
503a2a_invitation_membership_verification_unavailableRecipient membership could not be verified while accepting an email-bound invitation. Retry later.

Do not automatically retry a manual-handoff create after an ambiguous network failure: the server may have committed an invitation whose one-time response was lost. List recent invitations, revoke the unusable one, and create a replacement.