Skip to main content

unkey/models/
common.rs

1use serde::{Deserialize, Serialize};
2
3/// Response envelope wrapping all successful API responses.
4#[derive(Debug, Deserialize)]
5pub struct ApiResponse<T> {
6    pub meta: Meta,
7    pub data: T,
8}
9
10/// Paginated response envelope.
11#[derive(Debug, Deserialize)]
12pub struct PaginatedResponse<T> {
13    pub meta: Meta,
14    pub data: T,
15    pub pagination: Option<Pagination>,
16}
17
18/// Request metadata included in every API response.
19#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct Meta {
21    #[serde(rename = "requestId")]
22    pub request_id: String,
23}
24
25/// Pagination cursor for list endpoints.
26#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct Pagination {
28    pub cursor: Option<String>,
29    #[serde(rename = "hasMore")]
30    pub has_more: bool,
31}
32
33/// Error envelope from the Unkey API.
34#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct ErrorEnvelope {
36    pub meta: Meta,
37    pub error: ErrorDetail,
38}
39
40/// Structured error detail returned by the Unkey API.
41#[derive(Debug, Clone, Serialize, Deserialize)]
42pub struct ErrorDetail {
43    pub title: String,
44    pub detail: String,
45    pub status: u16,
46    #[serde(rename = "type")]
47    pub type_url: Option<String>,
48    #[serde(default)]
49    pub errors: Vec<ErrorItem>,
50}
51
52impl std::fmt::Display for ErrorDetail {
53    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54        write!(f, "{}: {}", self.title, self.detail)
55    }
56}
57
58/// Individual validation or field-level error.
59#[derive(Debug, Clone, Serialize, Deserialize)]
60pub struct ErrorItem {
61    pub message: String,
62    #[serde(default)]
63    pub location: Option<String>,
64    #[serde(default)]
65    pub fix: Option<String>,
66}
67
68/// Empty response data (for delete operations etc.)
69#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct EmptyResponse {}
71
72/// Identity linked to a key.
73#[derive(Debug, Clone, Serialize, Deserialize)]
74pub struct Identity {
75    pub id: String,
76    #[serde(rename = "externalId")]
77    pub external_id: String,
78    #[serde(default)]
79    pub meta: Option<serde_json::Value>,
80    #[serde(default)]
81    pub ratelimits: Vec<RatelimitResponse>,
82}
83
84/// Credit configuration for a key.
85#[derive(Debug, Clone, Serialize, Deserialize)]
86pub struct KeyCreditsData {
87    pub remaining: Option<i64>,
88    pub refill: Option<KeyCreditsRefill>,
89}
90
91/// Credit refill configuration.
92#[derive(Debug, Clone, Serialize, Deserialize)]
93pub struct KeyCreditsRefill {
94    pub interval: KeyCreditsRefillInterval,
95    pub amount: i64,
96    #[serde(rename = "refillDay")]
97    pub refill_day: Option<i64>,
98}
99
100/// Interval for credit refills.
101#[derive(Debug, Clone, Serialize, Deserialize)]
102#[serde(rename_all = "lowercase")]
103pub enum KeyCreditsRefillInterval {
104    Daily,
105    Monthly,
106}
107
108/// Rate limit configuration (for creating/updating keys).
109#[derive(Debug, Clone, Serialize, Deserialize)]
110pub struct RatelimitRequest {
111    pub name: String,
112    pub limit: i64,
113    pub duration: i64,
114    #[serde(rename = "autoApply", default)]
115    pub auto_apply: Option<bool>,
116}
117
118/// Rate limit response (returned with key data).
119#[derive(Debug, Clone, Serialize, Deserialize)]
120pub struct RatelimitResponse {
121    pub id: String,
122    pub name: String,
123    pub limit: i64,
124    pub duration: i64,
125    #[serde(rename = "autoApply")]
126    pub auto_apply: bool,
127}