space.highport.manage.getSiteTraffic
Schema Diff
+4 -0
Compatibility Analysis
Backward Compatible
Backward compatible. 2 non-breaking changes.
Non-Breaking Changes (2)
- AddedVertex AddedVertex { vertex_id: "space.highport.manage.getSiteTraffic:output.buckets:items.botRequests" }
- AddedEdge AddedEdge { src: "space.highport.manage.getSiteTraffic:output.buckets:items", tgt: "space.highport.manage.getSiteTraffic:output.buckets:items.botRequests", kind: "prop", name: Some("botRequests") }
Migration Guidance
Added Elements
AddedVertex { vertex_id: "space.highport.manage.getSiteTraffic:output.buckets:items.botRequests" }
Additional Notes
- Non-breaking: AddedEdge { src: "space.highport.manage.getSiteTraffic:output.buckets:items", tgt: "space.highport.manage.getSiteTraffic:output.buckets:items.botRequests", kind: "prop", name: Some("botRequests") }
1
1
{
2
2
"id": "space.highport.manage.getSiteTraffic",
3
3
"defs": {
4
4
"main": {
5
5
"type": "query",
6
6
"errors": [
7
7
{
8
8
"name": "InvalidDomain",
9
9
"description": "Not a syntactically valid, non-reserved, public-suffix-safe domain. Distinct from DomainNotFound: the string is not a hostname at all."
10
10
},
11
11
{
12
12
"name": "DomainNotFound",
13
13
"description": "No such domain, or it is not registered to the calling identity. The two are one answer so the method is not an existence oracle."
14
14
},
15
15
{
16
16
"name": "AnalyticsDisabled",
17
17
"description": "This deployment has no analytics store configured, so no traffic was ever recorded."
18
18
}
19
19
],
20
20
"output": {
21
21
"schema": {
22
22
"type": "object",
23
23
"required": [
24
24
"domain",
25
25
"bytesBilled",
26
26
"bytesBilledToVisitors",
27
27
"headerEstimateBytes",
28
28
"buckets",
29
29
"topPaths",
30
30
"statuses"
31
31
],
32
32
"properties": {
33
33
"domain": {
34
34
"type": "string"
35
35
},
36
36
"buckets": {
37
37
"type": "array",
38
38
"items": {
39
39
"type": "object",
40
40
"required": [
41
41
"bucket",
42
42
"requests",
43
43
"bytesBody",
44
44
"bytesBilled"
45
45
],
46
46
"properties": {
47
47
"bucket": {
48
48
"type": "string",
49
49
"format": "datetime",
50
50
"description": "The hour this bucket starts."
51
51
},
52
52
"requests": {
53
53
"type": "integer",
54
54
"description": "Responses in the hour."
55
55
},
56
56
"bytesBody": {
57
57
"type": "integer",
58
58
"description": "Response body bytes, as the edge logged them."
59
59
},
60
+
"botRequests": {
61
+
"type": "integer",
62
+
"description": "How many of requests came from a client classified as a crawler, which is a subset of it and not a sibling. There is no byte-level equivalent: the bucket carries no client_class split of bytesBody or bytesBilled. Absent from a deployment that does not report the split, which a reader shows as no answer rather than as no crawlers."
63
+
},
60
64
"bytesBilled": {
61
65
"type": "integer",
62
66
"description": "Body bytes plus the per-response header estimate."
63
67
}
64
68
},
65
69
"description": "One hour of a domain's traffic."
66
70
},
67
71
"description": "Hourly buckets, oldest first."
68
72
},
69
73
"records": {
70
74
"type": "array",
71
75
"items": {
72
76
"type": "object",
73
77
"required": [
74
78
"recordCid",
75
79
"firstSeen",
76
80
"requests",
77
81
"bytesBilled"
78
82
],
79
83
"properties": {
80
84
"lastSeen": {
81
85
"type": "string",
82
86
"format": "datetime",
83
87
"description": "The last, which with firstSeen is how long the version was serving inside the range — what makes one version's byte figure comparable to another's. Absent where the answer is not known, which a reader shows as still serving rather than as an interval it was not given."
84
88
},
85
89
"requests": {
86
90
"type": "integer",
87
91
"description": "Responses."
88
92
},
89
93
"firstSeen": {
90
94
"type": "string",
91
95
"format": "datetime",
92
96
"description": "The first response inside the range served from this version."
93
97
},
94
98
"recordCid": {
95
99
"type": "string",
96
100
"format": "cid",
97
101
"description": "The site record the serving snapshot was built from. Every response already names it, so the split needs nothing tagged."
98
102
},
99
103
"bytesBilled": {
100
104
"type": "integer",
101
105
"description": "Billed bytes."
102
106
}
103
107
},
104
108
"description": "One published version, and the traffic the snapshots built from it served."
105
109
},
106
110
"description": "Which published version of the site record served the traffic, heaviest first. Bounded by topRecords, so a domain republished more often than that has versions this does not list. Absent from a deployment that does not report the split."
107
111
},
108
112
"refusals": {
109
113
"type": "object",
110
114
"required": [
111
115
"requests"
112
116
],
113
117
"properties": {
114
118
"requests": {
115
119
"type": "integer",
116
120
"description": "Responses refused because the payer's allowance for the period was spent. The same responses the status mix counts as 402, taken from the same read so the two figures cannot disagree."
117
121
},
118
122
"estimatedBytes": {
119
123
"type": "integer",
120
124
"description": "What serving those responses instead would have charged the owner. Absent unless the deployment records it: a refusal transferred no body, so its cost is in no logged size, and only the edge knows how large the path it refused would have been."
121
125
}
122
126
},
123
127
"description": "What the bandwidth allowance refused over the range, and what serving it would have cost. Absent from a deployment that does not report it."
124
128
},
125
129
"statuses": {
126
130
"type": "array",
127
131
"items": {
128
132
"type": "object",
129
133
"required": [
130
134
"status",
131
135
"requests",
132
136
"bytesBilled",
133
137
"botRequests"
134
138
],
135
139
"properties": {
136
140
"status": {
137
141
"type": "integer",
138
142
"description": "The HTTP status."
139
143
},
140
144
"requests": {
141
145
"type": "integer",
142
146
"description": "Responses with this status."
143
147
},
144
148
"botRequests": {
145
149
"type": "integer",
146
150
"description": "How many of those came from a client classified as a crawler. Crawler traffic is billed, because it is real egress and the alternative rewards user-agent spoofing."
147
151
},
148
152
"bytesBilled": {
149
153
"type": "integer",
150
154
"description": "Billed bytes."
151
155
}
152
156
},
153
157
"description": "One status code's share of the requests and of the bytes."
154
158
},
155
159
"description": "The status mix, with the crawler share alongside it."
156
160
},
157
161
"topPaths": {
158
162
"type": "array",
159
163
"items": {
160
164
"type": "object",
161
165
"required": [
162
166
"path",
163
167
"requests",
164
168
"bytesBilled"
165
169
],
166
170
"properties": {
167
171
"path": {
168
172
"type": "string",
169
173
"description": "The request path."
170
174
},
171
175
"requests": {
172
176
"type": "integer",
173
177
"description": "Responses."
174
178
},
175
179
"bytesBilled": {
176
180
"type": "integer",
177
181
"description": "Billed bytes."
178
182
}
179
183
},
180
184
"description": "One path and what it cost."
181
185
},
182
186
"description": "The busiest paths over the range."
183
187
},
184
188
"bytesBilled": {
185
189
"type": "integer",
186
190
"description": "Total billed bytes over the range."
187
191
},
188
192
"headerEstimateBytes": {
189
193
"type": "integer",
190
194
"description": "The flat per-response constant added to every logged body size. Every byte figure here is an estimate by this much per response."
191
195
},
192
196
"bytesBilledToVisitors": {
193
197
"type": "integer",
194
198
"description": "How much of bytesBilled an authenticated visitor paid for rather than the owner. Zero unless the domain is on the sender-pays policy."
195
199
}
196
200
}
197
201
},
198
202
"encoding": "application/json"
199
203
},
200
204
"parameters": {
201
205
"type": "params",
202
206
"required": [
203
207
"domain"
204
208
],
205
209
"properties": {
206
210
"to": {
207
211
"type": "string",
208
212
"format": "datetime",
209
213
"description": "Exclusive upper bound. Defaults to now."
210
214
},
211
215
"from": {
212
216
"type": "string",
213
217
"format": "datetime",
214
218
"description": "Inclusive lower bound. Defaults to 30 days ago."
215
219
},
216
220
"domain": {
217
221
"type": "string",
218
222
"maxLength": 253,
219
223
"description": "The registered hostname. Must be registered to the calling identity."
220
224
},
221
225
"topPaths": {
222
226
"type": "integer",
223
227
"default": 20,
224
228
"maximum": 100,
225
229
"minimum": 0,
226
230
"description": "How many of the busiest paths to return."
227
231
},
228
232
"topRecords": {
229
233
"type": "integer",
230
234
"default": 20,
231
235
"maximum": 100,
232
236
"minimum": 0,
233
237
"description": "How many published record versions to return. A record CID is not a small set: a domain republished often has one per publish, so this is a top-N and not the whole history."
234
238
}
235
239
}
236
240
},
237
241
"description": "Traffic to one domain the caller owns, over a range: requests and bytes per hour, the busiest paths, and the status mix. Byte figures include a flat per-response header estimate, because the edge's access log records the response body only."
238
242
}
239
243
},
240
244
"$type": "com.atproto.lexicon.schema",
241
245
"lexicon": 1
242
246
}