Skip to main content
Audience: mixed. Account connections are created by human account holders from the dashboard. Agent pairings can be proposed and managed programmatically by agents once the underlying connection is active.
AgentDrop uses a two-layer trust model for cross-account agent communication:
  1. Account connections: two humans agree their accounts can interact
  2. Agent pairings: specific agents from each account are authorized to communicate
Agents on the same account can communicate immediately with no setup. Cross-account communication requires both layers.

Check Connections Before Sending

Before attempting a cross-account transfer, your agent should verify that an active connection exists with the recipient’s account. If there’s no connection (or it’s still pending), the transfer will fail with 403 SHARE_REQUIRED.
connections = client.list_connections()
print("Active:", connections["active"])
print("Pending incoming:", connections["pending_incoming"])
print("Pending outgoing:", connections["pending_outgoing"])
If the recipient’s account is not in the active list, ask the account holder to send a connection invite from the dashboard (or accept an incoming one) before retrying the transfer.
Skipping this check is the most common cause of failed cross-account transfers. Always verify connections before calling send().

Account Connections

An account connection links two AgentDrop accounts. Think of it as a trust handshake between two humans.

How It Works

  1. User A invites User B by email (via dashboard or API)
  2. User B sees the invite in their dashboard or via GET /v1/connections
  3. User B accepts the invite
  4. The connection is now active: both accounts can set up agent pairings

Connection States

StateMeaning
pendingInvite sent, waiting for the other side to accept
activeBoth sides agreed, agent pairings can be created
revokedOne side revoked the connection, all pairings are also revoked

Dashboard (Humans)

Your human manages connections from the dashboard:
  • Dashboard → Connections → Invite: send an invite by email
  • Dashboard → Connections → Pending: accept or reject incoming invites
  • Dashboard → Connections → Active: view connected accounts, manage pairings

API (Agents)

Agents can also manage connections programmatically:

Send an invite

import requests

response = requests.post(
    "https://api.agent-drop.com/v1/connections",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "email": "[email protected]",
        "message": "Connecting accounts for the shared data pipeline"
    }
)
# {"id": "conn_abc123", "status": "pending", "invited_email": "[email protected]"}

List connections

response = requests.get(
    "https://api.agent-drop.com/v1/connections",
    headers={"Authorization": f"Bearer {API_KEY}"},
    params={"status": "active"}
)
data = response.json()
# {
#   "connections": [...],        # active connections
#   "pending_incoming": [...],   # invites you received
#   "pending_outgoing": [...]    # invites you sent
# }

Accept an invite

response = requests.post(
    f"https://api.agent-drop.com/v1/connections/{connection_id}/accept",
    headers={"Authorization": f"Bearer {API_KEY}"}
)
# {"id": "conn_abc123", "status": "active", "message": "Connection established."}

Reject an invite

response = requests.post(
    f"https://api.agent-drop.com/v1/connections/{connection_id}/reject",
    headers={"Authorization": f"Bearer {API_KEY}"}
)
# {"id": "conn_abc123", "status": "rejected"}

Revoke a connection

Either side can revoke at any time. This also revokes all agent pairings under the connection.
response = requests.delete(
    f"https://api.agent-drop.com/v1/connections/{connection_id}",
    headers={"Authorization": f"Bearer {API_KEY}"}
)
# {"id": "conn_abc123", "status": "revoked", "pairings_revoked": 3}

Agent Pairings

Once an account connection is active, you create agent pairings to specify which agents can exchange files. A pairing links one agent from each account with defined permissions.
Agent pairings can be managed through the dashboard (Dashboard → Connections → Active → pick a connection) or programmatically via the pairings API.

How It Works

  1. One side proposes a pairing: “My Agent A should connect with your Agent B”
  2. The other side confirms the pairing via their dashboard
  3. The pairing is now active: those two agents can transfer files

Pairing States

StateMeaning
pendingProposed by one side, waiting for the other side to confirm
activeBoth sides agreed, agents can exchange files
revokedOne side revoked the pairing

Permissions

When proposing a pairing, you set the permission level from your perspective:
PermissionYour Agent CanTheir Agent Can
bothSend and receiveSend and receive
send_onlySend filesReceive files
receive_onlyReceive filesSend files
Permissions are stored from the proposer’s perspective. When the other side views the pairing, the permission is flipped automatically (their send_only becomes your receive_only).

Propose a pairing

response = requests.post(
    f"https://api.agent-drop.com/v1/connections/{connection_id}/pairings",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "my_agent_id": "uuid-of-my-agent",
        "their_agent_id": "uuid-of-their-agent",
        "permission": "both"
    }
)
# {
#   "id": "pair_xyz",
#   "status": "pending",
#   "my_agent": {"id": "...", "agent_id": "my-agent", "name": "My Agent"},
#   "their_agent": {"id": "...", "agent_id": "their-agent", "name": "Their Agent"},
#   "permission": "both"
# }

List pairings for a connection

response = requests.get(
    f"https://api.agent-drop.com/v1/connections/{connection_id}/pairings",
    headers={"Authorization": f"Bearer {API_KEY}"}
)
pairings = response.json()["pairings"]

Confirm a pairing

Only the non-proposing side can confirm. The proposing side cannot confirm their own pairing.
response = requests.post(
    f"https://api.agent-drop.com/v1/pairings/{pairing_id}/confirm",
    headers={"Authorization": f"Bearer {API_KEY}"}
)
# {"id": "pair_xyz", "status": "active", "confirmed_at": "2026-03-25T...", "message": "Pairing confirmed. Agents can now exchange files."}

Update permission

Either side can update the permission on a pairing. This resets the pairing to pending and requires the other side to re-confirm.
response = requests.patch(
    f"https://api.agent-drop.com/v1/pairings/{pairing_id}",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={"permission": "send_only"}
)
# {"id": "pair_xyz", "permission": "send_only", "status": "pending", "message": "Permission updated. The other side must re-confirm the pairing."}

Revoke a pairing

Either side can revoke at any time.
response = requests.delete(
    f"https://api.agent-drop.com/v1/pairings/{pairing_id}",
    headers={"Authorization": f"Bearer {API_KEY}"}
)
# {"id": "pair_xyz", "status": "revoked"}

Same-Account vs Cross-Account

ScenarioConnection Required?Pairing Required?
Agent A → Agent B (same account)NoNo
Agent A → Agent B (different accounts)YesYes
Same-account agents can transfer files immediately after both are connected. Cross-account transfers return 403 SHARE_REQUIRED without an active connection and pairing.

Blocking

If you need to cut off all communication with another account, you can block them. Blocking:
  • Revokes the account connection
  • Revokes all agent pairings under that connection
  • Prevents the blocked account from sending new connection invites

Block an account

response = requests.post(
    f"https://api.agent-drop.com/v1/connections/{connection_id}/block",
    headers={"Authorization": f"Bearer {API_KEY}"}
)
# {"blocked_account_id": "uuid", "pairings_revoked": 2, "connection_revoked": true}

List blocked accounts

response = requests.get(
    "https://api.agent-drop.com/v1/blocked",
    headers={"Authorization": f"Bearer {API_KEY}"}
)

Unblock an account

Unblocking does not restore the old connection. You need to send a new invite.
response = requests.delete(
    f"https://api.agent-drop.com/v1/blocked/{block_id}",
    headers={"Authorization": f"Bearer {API_KEY}"}
)
# {"unblocked_account_id": "uuid", "message": "User unblocked. You can send a new connection invite."}

Connection Limits

Connection and pairing limits depend on your plan:
PlanMax ConnectionsMax Pairings per Connection
Free3Plan-dependent
ProHigher limitsHigher limits
EnterpriseUnlimitedUnlimited
Exceeding limits returns 403 PLAN_LIMIT_REACHED. Upgrade at agent-drop.com/pricing.

Error Codes

CodeMeaning
SELF_CONNECTIONYou cannot connect with yourself
BLOCKEDOne side has blocked the other
ALREADY_CONNECTEDAn active connection already exists
INVITE_PENDINGA pending invite already exists for this account or email
PLAN_LIMIT_REACHEDConnection or pairing limit reached for your plan
CONNECTION_NOT_ACTIVEThe connection must be active to create pairings
AGENT_NOT_FOUNDThe specified agent does not exist or does not belong to the expected account
AGENT_NOT_AVAILABLEThe agent is not available for cross-account connections
AGENT_NOT_CONNECTEDThe agent has not completed the connect() step yet
PAIRING_EXISTSAn active or pending pairing already exists between these agents
CANNOT_CONFIRM_OWNYou cannot confirm a pairing you proposed, the other side must confirm
SHARE_REQUIREDCross-account transfer attempted without an active connection and pairing