Skip to main content

agentmail/types/
api_keys.rs

1use serde::{Deserialize, Serialize};
2use std::collections::BTreeMap;
3
4/// An API key's permission flags, keyed by permission name (e.g.
5/// `message_send`, `calendar_event_create`). Modeled as a map so permission
6/// additions don't require a client release; unknown names are preserved.
7pub type ApiKeyPermissions = BTreeMap<String, bool>;
8
9/// The public-key material bound to a `public_key` API key (JWK plus its
10/// RFC 7638 thumbprint), as the API returns it.
11#[derive(Clone, Debug, Deserialize)]
12pub struct PublicKeyMaterial {
13    /// The public JWK (`kty`, `crv`, `x`, `y`).
14    #[serde(default)]
15    pub jwk: Option<serde_json::Value>,
16    /// Unpadded base64url RFC 7638 SHA-256 thumbprint of the JWK.
17    #[serde(default)]
18    pub fingerprint: Option<String>,
19}
20
21/// The agent that created a `public_key` API key.
22#[derive(Clone, Debug, Deserialize)]
23pub struct ApiKeyCreator {
24    /// The creating key's id.
25    pub api_key_id: String,
26}
27
28/// An API key, as the API returns it. The wire shape is a oneOf over bearer
29/// keys and `public_key` credentials; every field defaults so both parse.
30/// The secret material itself is never returned here (see [`CreatedApiKey`]).
31#[derive(Clone, Debug, Deserialize)]
32pub struct ApiKey {
33    /// `bearer` or `public_key`.
34    #[serde(rename = "type", default)]
35    pub key_type: Option<String>,
36    /// Unique key id.
37    pub api_key_id: String,
38    /// The key's non-secret prefix, for identification.
39    #[serde(default)]
40    pub prefix: Option<String>,
41    /// Human-readable name.
42    #[serde(default)]
43    pub name: Option<String>,
44    /// The pod the key is scoped to, when applicable.
45    #[serde(default)]
46    pub pod_id: Option<String>,
47    /// The inbox the key is scoped to, when applicable.
48    #[serde(default)]
49    pub inbox_id: Option<String>,
50    /// Your reference id, for `public_key` credentials.
51    #[serde(default)]
52    pub client_id: Option<String>,
53    /// Public-key material, for `public_key` credentials.
54    #[serde(default)]
55    pub public_key: Option<PublicKeyMaterial>,
56    /// Registration state of a `public_key` credential: `pending` or `active`.
57    #[serde(default)]
58    pub status: Option<String>,
59    /// When the key was last used (RFC 3339).
60    #[serde(default)]
61    pub used_at: Option<String>,
62    /// The key's permissions.
63    #[serde(default)]
64    pub permissions: Option<ApiKeyPermissions>,
65    /// The key that created this one, for `public_key` credentials.
66    #[serde(default)]
67    pub created_by: Option<ApiKeyCreator>,
68    /// When the key was created (RFC 3339).
69    #[serde(default)]
70    pub created_at: Option<String>,
71    /// When the key was last updated (RFC 3339).
72    #[serde(default)]
73    pub updated_at: Option<String>,
74    /// When the key stops working (RFC 3339), when it expires.
75    #[serde(default)]
76    pub expires_at: Option<String>,
77}
78
79/// Request body for `create_api_key`. The default (no `public_key`) mints a
80/// bearer key; setting `public_key` registers a `public_key` credential
81/// instead. The full secret of a bearer key is returned exactly once, in
82/// [`CreatedApiKey::api_key`].
83#[derive(Clone, Debug, Default, Serialize)]
84pub struct CreateApiKey {
85    /// Human-readable name for the key.
86    #[serde(skip_serializing_if = "Option::is_none")]
87    pub name: Option<String>,
88    /// The permissions to grant.
89    #[serde(skip_serializing_if = "Option::is_none")]
90    pub permissions: Option<ApiKeyPermissions>,
91    /// When the key should stop working (RFC 3339).
92    #[serde(skip_serializing_if = "Option::is_none")]
93    pub expires_at: Option<String>,
94    /// Your reference id, when registering a `public_key` credential.
95    #[serde(skip_serializing_if = "Option::is_none")]
96    pub client_id: Option<String>,
97    /// The public JWK (`kty`, `crv`, `x`, `y`); its presence selects the
98    /// `public_key` credential flow.
99    #[serde(skip_serializing_if = "Option::is_none")]
100    pub public_key: Option<serde_json::Value>,
101}
102
103/// Body for `update_api_key`. Fields left `None` stay unchanged.
104#[derive(Clone, Debug, Default, Serialize)]
105pub struct UpdateApiKey {
106    /// Replace the human-readable name.
107    #[serde(skip_serializing_if = "Option::is_none")]
108    pub name: Option<String>,
109    /// Replace the permission set.
110    #[serde(skip_serializing_if = "Option::is_none")]
111    pub permissions: Option<ApiKeyPermissions>,
112}
113
114/// The response to `create_api_key`. The full `api_key` secret is
115/// returned exactly once, here; store it now, as it cannot be retrieved again.
116#[derive(Clone, Debug, Deserialize)]
117pub struct CreatedApiKey {
118    /// Unique key id.
119    pub api_key_id: String,
120    /// The full secret key. Shown only on creation.
121    pub api_key: String,
122    /// The key's non-secret prefix.
123    #[serde(default)]
124    pub prefix: Option<String>,
125    /// Human-readable name.
126    #[serde(default)]
127    pub name: Option<String>,
128    /// The pod the key is scoped to, when applicable.
129    #[serde(default)]
130    pub pod_id: Option<String>,
131    /// The inbox the key is scoped to, when applicable.
132    #[serde(default)]
133    pub inbox_id: Option<String>,
134    /// The granted permissions.
135    #[serde(default)]
136    pub permissions: Option<ApiKeyPermissions>,
137    /// When the key was created (RFC 3339).
138    #[serde(default)]
139    pub created_at: Option<String>,
140}
141
142/// One page of API keys from `list_api_keys_page`.
143#[derive(Clone, Debug, Deserialize)]
144pub struct ApiKeyList {
145    /// Total keys in the account (not just this page).
146    pub count: u64,
147    /// This page of keys.
148    #[serde(default)]
149    pub api_keys: Vec<ApiKey>,
150    /// Cursor for the next page; `None` on the last page.
151    #[serde(default)]
152    pub next_page_token: Option<String>,
153}