foil-server 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +154 -0
  4. data/lib/foil/server/client.rb +472 -0
  5. data/lib/foil/server/crypto_support.rb +49 -0
  6. data/lib/foil/server/errors.rb +21 -0
  7. data/lib/foil/server/gate_delivery.rb +325 -0
  8. data/lib/foil/server/sealed_token.rb +78 -0
  9. data/lib/foil/server/types.rb +5 -0
  10. data/lib/foil/server/version.rb +5 -0
  11. data/lib/foil/server.rb +31 -0
  12. data/spec/LICENSE +21 -0
  13. data/spec/README.md +160 -0
  14. data/spec/fixtures/api/fingerprints/detail.json +70 -0
  15. data/spec/fixtures/api/fingerprints/list.json +37 -0
  16. data/spec/fixtures/api/gate/agent-token-revoke.json +3 -0
  17. data/spec/fixtures/api/gate/agent-token-verify.json +12 -0
  18. data/spec/fixtures/api/gate/login-session-consume.json +10 -0
  19. data/spec/fixtures/api/gate/login-session-create.json +12 -0
  20. data/spec/fixtures/api/gate/registry-detail.json +45 -0
  21. data/spec/fixtures/api/gate/registry-list.json +47 -0
  22. data/spec/fixtures/api/gate/service-create.json +49 -0
  23. data/spec/fixtures/api/gate/service-detail.json +49 -0
  24. data/spec/fixtures/api/gate/service-disable.json +49 -0
  25. data/spec/fixtures/api/gate/service-update.json +49 -0
  26. data/spec/fixtures/api/gate/services-list.json +51 -0
  27. data/spec/fixtures/api/gate/session-ack.json +10 -0
  28. data/spec/fixtures/api/gate/session-create.json +13 -0
  29. data/spec/fixtures/api/gate/session-poll.json +36 -0
  30. data/spec/fixtures/api/organizations/api-key-create.json +27 -0
  31. data/spec/fixtures/api/organizations/api-key-list.json +31 -0
  32. data/spec/fixtures/api/organizations/api-key-revoke.json +25 -0
  33. data/spec/fixtures/api/organizations/api-key-rotate.json +27 -0
  34. data/spec/fixtures/api/organizations/api-key-update.json +29 -0
  35. data/spec/fixtures/api/organizations/organization-create.json +14 -0
  36. data/spec/fixtures/api/organizations/organization-update.json +14 -0
  37. data/spec/fixtures/api/organizations/organization.json +14 -0
  38. data/spec/fixtures/api/sessions/detail.json +434 -0
  39. data/spec/fixtures/api/sessions/list.json +36 -0
  40. data/spec/fixtures/errors/invalid-api-key.json +10 -0
  41. data/spec/fixtures/errors/missing-api-key.json +10 -0
  42. data/spec/fixtures/errors/not-found.json +10 -0
  43. data/spec/fixtures/errors/validation-error.json +20 -0
  44. data/spec/fixtures/gate-delivery/approved-webhook-payload.valid.json +19 -0
  45. data/spec/fixtures/gate-delivery/delivery-request.json +9 -0
  46. data/spec/fixtures/gate-delivery/env-policy.json +40 -0
  47. data/spec/fixtures/gate-delivery/vector.v1.json +28 -0
  48. data/spec/fixtures/gate-delivery/webhook-signature.json +9 -0
  49. data/spec/fixtures/manifest.json +185 -0
  50. data/spec/fixtures/sealed-token/invalid.json +4 -0
  51. data/spec/fixtures/sealed-token/vector.v1.json +54 -0
  52. data/spec/openapi.json +20482 -0
  53. data/spec/sealed-token.md +114 -0
  54. metadata +96 -0
@@ -0,0 +1,70 @@
1
+ {
2
+ "data": {
3
+ "object": "visitor_fingerprint",
4
+ "id": "vid_456789abcdefghjkmnpqrstvwx",
5
+ "lifecycle": {
6
+ "first_seen_at": "2026-03-24T19:58:00.000Z",
7
+ "last_seen_at": "2026-03-24T20:00:05.000Z",
8
+ "seen_count": 3,
9
+ "expires_at": "2026-06-22T20:00:05.000Z"
10
+ },
11
+ "latest_request": {
12
+ "user_agent": "Mozilla/5.0",
13
+ "ip_address": "203.0.113.9"
14
+ },
15
+ "storage": {
16
+ "cookies": true,
17
+ "local_storage": true,
18
+ "indexed_db": true,
19
+ "service_worker": false,
20
+ "window_name": false
21
+ },
22
+ "anchors": {
23
+ "webgl_hash": null,
24
+ "parameters_hash": null,
25
+ "audio_hash": null
26
+ },
27
+ "components": {
28
+ "vector": [
29
+ 1,
30
+ 0,
31
+ 1
32
+ ]
33
+ },
34
+ "activity": {
35
+ "sessions": [
36
+ {
37
+ "session_id": "sid_0123456789abcdefghjkmnpqrs",
38
+ "decision": {
39
+ "event_id": "evt_23456789abcdefghjkmnpqrstv",
40
+ "verdict": "human",
41
+ "risk_score": 9,
42
+ "phase": "behavioral",
43
+ "is_provisional": false,
44
+ "manipulation": {
45
+ "score": 0,
46
+ "verdict": "none"
47
+ },
48
+ "evaluation_duration_ms": 142,
49
+ "evaluated_at": "2026-03-24T20:00:05.000Z"
50
+ },
51
+ "request": {
52
+ "url": "https://example.com/signup",
53
+ "user_agent": "Mozilla/5.0",
54
+ "ip_address": "203.0.113.9",
55
+ "screen_size": "1440x900",
56
+ "is_touch_capable": false
57
+ },
58
+ "score_breakdown": {
59
+ "categories": {
60
+ "behavioral": 9
61
+ }
62
+ }
63
+ }
64
+ ]
65
+ }
66
+ },
67
+ "meta": {
68
+ "request_id": "req_0123456789abcdef0123456789abcdef"
69
+ }
70
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "data": [
3
+ {
4
+ "object": "visitor_fingerprint",
5
+ "id": "vid_456789abcdefghjkmnpqrstvwx",
6
+ "lifecycle": {
7
+ "first_seen_at": "2026-03-24T19:58:00.000Z",
8
+ "last_seen_at": "2026-03-24T20:00:05.000Z",
9
+ "seen_count": 3,
10
+ "expires_at": "2026-06-22T20:00:05.000Z"
11
+ },
12
+ "latest_request": {
13
+ "user_agent": "Mozilla/5.0",
14
+ "ip_address": "203.0.113.9"
15
+ },
16
+ "storage": {
17
+ "cookies": true,
18
+ "local_storage": true,
19
+ "indexed_db": true,
20
+ "service_worker": false,
21
+ "window_name": false
22
+ },
23
+ "anchors": {
24
+ "webgl_hash": null,
25
+ "parameters_hash": null,
26
+ "audio_hash": null
27
+ }
28
+ }
29
+ ],
30
+ "pagination": {
31
+ "limit": 50,
32
+ "has_more": false
33
+ },
34
+ "meta": {
35
+ "request_id": "req_0123456789abcdef0123456789abcdef"
36
+ }
37
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "status": 204
3
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "data": {
3
+ "valid": true,
4
+ "gate_account_id": "gacct_0123456789abcdefghjkmnpqrs",
5
+ "status": "active",
6
+ "created_at": "2026-04-01T12:00:00.000Z",
7
+ "expires_at": "2026-06-30T12:00:00.000Z"
8
+ },
9
+ "meta": {
10
+ "request_id": "req_0123456789abcdef0123456789abcdef"
11
+ }
12
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "data": {
3
+ "object": "gate_dashboard_login",
4
+ "gate_account_id": "gacct_0123456789abcdefghjkmnpqrs",
5
+ "account_name": "my-project"
6
+ },
7
+ "meta": {
8
+ "request_id": "req_0123456789abcdef0123456789abcdef"
9
+ }
10
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "data": {
3
+ "object": "gate_login_session",
4
+ "id": "gate_1123456789abcdefghjkmnpqrs",
5
+ "status": "pending",
6
+ "consent_url": "https://usefoil.com/gate?session=gate_1123456789abcdefghjkmnpqrs",
7
+ "expires_at": "2026-04-04T20:20:00.000Z"
8
+ },
9
+ "meta": {
10
+ "request_id": "req_0123456789abcdef0123456789abcdef"
11
+ }
12
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ "data": {
3
+ "id": "foil",
4
+ "status": "active",
5
+ "discoverable": true,
6
+ "name": "Foil",
7
+ "description": "Detect AI agents and malicious users",
8
+ "website": "https://usefoil.com",
9
+ "dashboard_login_url": "https://dashboard.usefoil.com/auth/gate",
10
+ "env_vars": [
11
+ {
12
+ "name": "Publishable key",
13
+ "key": "FOIL_PUBLISHABLE_KEY",
14
+ "secret": false
15
+ },
16
+ {
17
+ "name": "Secret key",
18
+ "key": "FOIL_SECRET_KEY",
19
+ "secret": true
20
+ }
21
+ ],
22
+ "docs_url": "https://usefoil.com/docs",
23
+ "sdks": [
24
+ {
25
+ "label": "Node",
26
+ "install": "npm install @abxy/foil-server",
27
+ "url": "https://www.npmjs.com/package/@abxy/foil-server"
28
+ }
29
+ ],
30
+ "branding": {
31
+ "logo_url": "https://usefoil.com/logo.png",
32
+ "primary_color": "#117BE7",
33
+ "secondary_color": "#0B5CAD",
34
+ "ascii_art": "FOIL",
35
+ "verified": true
36
+ },
37
+ "consent": {
38
+ "terms_url": "https://usefoil.com/terms",
39
+ "privacy_url": "https://usefoil.com/privacy"
40
+ }
41
+ },
42
+ "meta": {
43
+ "request_id": "req_0123456789abcdef0123456789abcdef"
44
+ }
45
+ }
@@ -0,0 +1,47 @@
1
+ {
2
+ "data": [
3
+ {
4
+ "id": "foil",
5
+ "status": "active",
6
+ "discoverable": true,
7
+ "name": "Foil",
8
+ "description": "Detect AI agents and malicious users",
9
+ "website": "https://usefoil.com",
10
+ "dashboard_login_url": "https://dashboard.usefoil.com/auth/gate",
11
+ "env_vars": [
12
+ {
13
+ "name": "Publishable key",
14
+ "key": "FOIL_PUBLISHABLE_KEY",
15
+ "secret": false
16
+ },
17
+ {
18
+ "name": "Secret key",
19
+ "key": "FOIL_SECRET_KEY",
20
+ "secret": true
21
+ }
22
+ ],
23
+ "docs_url": "https://usefoil.com/docs",
24
+ "sdks": [
25
+ {
26
+ "label": "Node",
27
+ "install": "npm install @abxy/foil-server",
28
+ "url": "https://www.npmjs.com/package/@abxy/foil-server"
29
+ }
30
+ ],
31
+ "branding": {
32
+ "logo_url": "https://usefoil.com/logo.png",
33
+ "primary_color": "#117BE7",
34
+ "secondary_color": "#0B5CAD",
35
+ "ascii_art": "FOIL",
36
+ "verified": true
37
+ },
38
+ "consent": {
39
+ "terms_url": "https://usefoil.com/terms",
40
+ "privacy_url": "https://usefoil.com/privacy"
41
+ }
42
+ }
43
+ ],
44
+ "meta": {
45
+ "request_id": "req_0123456789abcdef0123456789abcdef"
46
+ }
47
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "data": {
3
+ "object": "gate_service",
4
+ "id": "acme_prod",
5
+ "status": "active",
6
+ "discoverable": false,
7
+ "name": "Acme Production",
8
+ "description": "Acme production signup flow",
9
+ "website": "https://acme.example.com",
10
+ "dashboard_login_url": "https://dashboard.acme.example.com/auth/gate",
11
+ "env_vars": [
12
+ {
13
+ "name": "Publishable key",
14
+ "key": "ACME_PUBLISHABLE_KEY",
15
+ "secret": false
16
+ },
17
+ {
18
+ "name": "Secret key",
19
+ "key": "ACME_SECRET_KEY",
20
+ "secret": true
21
+ }
22
+ ],
23
+ "docs_url": "https://docs.acme.example.com/signup",
24
+ "sdks": [
25
+ {
26
+ "label": "Node",
27
+ "install": "npm install @acme/sdk",
28
+ "url": "https://www.npmjs.com/package/@acme/sdk"
29
+ }
30
+ ],
31
+ "branding": {
32
+ "logo_url": "https://acme.example.com/logo.png",
33
+ "primary_color": "#117BE7",
34
+ "secondary_color": "#0B5CAD",
35
+ "ascii_art": "ACME",
36
+ "verified": false
37
+ },
38
+ "consent": {
39
+ "terms_url": "https://acme.example.com/terms",
40
+ "privacy_url": "https://acme.example.com/privacy"
41
+ },
42
+ "created_at": "2026-04-03T20:00:00.000Z",
43
+ "updated_at": "2026-04-03T20:00:00.000Z",
44
+ "webhook_endpoint_id": "we_0123456789abcdef0123456789abcdef"
45
+ },
46
+ "meta": {
47
+ "request_id": "req_0123456789abcdef0123456789abcdef"
48
+ }
49
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "data": {
3
+ "object": "gate_service",
4
+ "id": "acme_prod",
5
+ "status": "active",
6
+ "discoverable": false,
7
+ "name": "Acme Production",
8
+ "description": "Acme production signup flow",
9
+ "website": "https://acme.example.com",
10
+ "dashboard_login_url": "https://dashboard.acme.example.com/auth/gate",
11
+ "env_vars": [
12
+ {
13
+ "name": "Publishable key",
14
+ "key": "ACME_PUBLISHABLE_KEY",
15
+ "secret": false
16
+ },
17
+ {
18
+ "name": "Secret key",
19
+ "key": "ACME_SECRET_KEY",
20
+ "secret": true
21
+ }
22
+ ],
23
+ "docs_url": "https://docs.acme.example.com/signup",
24
+ "sdks": [
25
+ {
26
+ "label": "Node",
27
+ "install": "npm install @acme/sdk",
28
+ "url": "https://www.npmjs.com/package/@acme/sdk"
29
+ }
30
+ ],
31
+ "branding": {
32
+ "logo_url": "https://acme.example.com/logo.png",
33
+ "primary_color": "#117BE7",
34
+ "secondary_color": "#0B5CAD",
35
+ "ascii_art": "ACME",
36
+ "verified": false
37
+ },
38
+ "consent": {
39
+ "terms_url": "https://acme.example.com/terms",
40
+ "privacy_url": "https://acme.example.com/privacy"
41
+ },
42
+ "created_at": "2026-04-03T20:00:00.000Z",
43
+ "updated_at": "2026-04-03T20:05:00.000Z",
44
+ "webhook_endpoint_id": "we_0123456789abcdef0123456789abcdef"
45
+ },
46
+ "meta": {
47
+ "request_id": "req_0123456789abcdef0123456789abcdef"
48
+ }
49
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "data": {
3
+ "object": "gate_service",
4
+ "id": "acme_prod",
5
+ "status": "disabled",
6
+ "discoverable": false,
7
+ "name": "Acme Production",
8
+ "description": "Acme production signup flow",
9
+ "website": "https://acme.example.com",
10
+ "dashboard_login_url": "https://dashboard.acme.example.com/auth/gate",
11
+ "env_vars": [
12
+ {
13
+ "name": "Publishable key",
14
+ "key": "ACME_PUBLISHABLE_KEY",
15
+ "secret": false
16
+ },
17
+ {
18
+ "name": "Secret key",
19
+ "key": "ACME_SECRET_KEY",
20
+ "secret": true
21
+ }
22
+ ],
23
+ "docs_url": "https://docs.acme.example.com/signup",
24
+ "sdks": [
25
+ {
26
+ "label": "Node",
27
+ "install": "npm install @acme/sdk",
28
+ "url": "https://www.npmjs.com/package/@acme/sdk"
29
+ }
30
+ ],
31
+ "branding": {
32
+ "logo_url": "https://acme.example.com/logo.png",
33
+ "primary_color": "#117BE7",
34
+ "secondary_color": "#0B5CAD",
35
+ "ascii_art": "ACME",
36
+ "verified": false
37
+ },
38
+ "consent": {
39
+ "terms_url": "https://acme.example.com/terms",
40
+ "privacy_url": "https://acme.example.com/privacy"
41
+ },
42
+ "created_at": "2026-04-03T20:00:00.000Z",
43
+ "updated_at": "2026-04-03T20:15:00.000Z",
44
+ "webhook_endpoint_id": "we_0123456789abcdef0123456789abcdef"
45
+ },
46
+ "meta": {
47
+ "request_id": "req_0123456789abcdef0123456789abcdef"
48
+ }
49
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "data": {
3
+ "object": "gate_service",
4
+ "id": "acme_prod",
5
+ "status": "active",
6
+ "discoverable": true,
7
+ "name": "Acme Production",
8
+ "description": "Acme production signup flow",
9
+ "website": "https://acme.example.com",
10
+ "dashboard_login_url": "https://dashboard.acme.example.com/auth/gate",
11
+ "env_vars": [
12
+ {
13
+ "name": "Publishable key",
14
+ "key": "ACME_PUBLISHABLE_KEY",
15
+ "secret": false
16
+ },
17
+ {
18
+ "name": "Secret key",
19
+ "key": "ACME_SECRET_KEY",
20
+ "secret": true
21
+ }
22
+ ],
23
+ "docs_url": "https://docs.acme.example.com/signup",
24
+ "sdks": [
25
+ {
26
+ "label": "Node",
27
+ "install": "npm install @acme/sdk",
28
+ "url": "https://www.npmjs.com/package/@acme/sdk"
29
+ }
30
+ ],
31
+ "branding": {
32
+ "logo_url": "https://acme.example.com/logo.png",
33
+ "primary_color": "#117BE7",
34
+ "secondary_color": "#0B5CAD",
35
+ "ascii_art": "ACME",
36
+ "verified": false
37
+ },
38
+ "consent": {
39
+ "terms_url": "https://acme.example.com/terms",
40
+ "privacy_url": "https://acme.example.com/privacy"
41
+ },
42
+ "created_at": "2026-04-03T20:00:00.000Z",
43
+ "updated_at": "2026-04-03T20:10:00.000Z",
44
+ "webhook_endpoint_id": "we_0123456789abcdef0123456789abcdef"
45
+ },
46
+ "meta": {
47
+ "request_id": "req_0123456789abcdef0123456789abcdef"
48
+ }
49
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "data": [
3
+ {
4
+ "object": "gate_service",
5
+ "id": "acme_prod",
6
+ "status": "active",
7
+ "discoverable": false,
8
+ "name": "Acme Production",
9
+ "description": "Acme production signup flow",
10
+ "website": "https://acme.example.com",
11
+ "dashboard_login_url": "https://dashboard.acme.example.com/auth/gate",
12
+ "env_vars": [
13
+ {
14
+ "name": "Publishable key",
15
+ "key": "ACME_PUBLISHABLE_KEY",
16
+ "secret": false
17
+ },
18
+ {
19
+ "name": "Secret key",
20
+ "key": "ACME_SECRET_KEY",
21
+ "secret": true
22
+ }
23
+ ],
24
+ "docs_url": "https://docs.acme.example.com/signup",
25
+ "sdks": [
26
+ {
27
+ "label": "Node",
28
+ "install": "npm install @acme/sdk",
29
+ "url": "https://www.npmjs.com/package/@acme/sdk"
30
+ }
31
+ ],
32
+ "branding": {
33
+ "logo_url": "https://acme.example.com/logo.png",
34
+ "primary_color": "#117BE7",
35
+ "secondary_color": "#0B5CAD",
36
+ "ascii_art": "ACME",
37
+ "verified": false
38
+ },
39
+ "consent": {
40
+ "terms_url": "https://acme.example.com/terms",
41
+ "privacy_url": "https://acme.example.com/privacy"
42
+ },
43
+ "created_at": "2026-04-03T20:00:00.000Z",
44
+ "updated_at": "2026-04-03T20:05:00.000Z",
45
+ "webhook_endpoint_id": "we_0123456789abcdef0123456789abcdef"
46
+ }
47
+ ],
48
+ "meta": {
49
+ "request_id": "req_0123456789abcdef0123456789abcdef"
50
+ }
51
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "data": {
3
+ "object": "gate_session_delivery",
4
+ "gate_session_id": "gate_0123456789abcdefghjkmnpqrs",
5
+ "status": "acknowledged"
6
+ },
7
+ "meta": {
8
+ "request_id": "req_0123456789abcdef0123456789abcdef"
9
+ }
10
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "data": {
3
+ "object": "gate_session",
4
+ "id": "gate_0123456789abcdefghjkmnpqrs",
5
+ "status": "pending",
6
+ "poll_token": "gtpoll_0123456789abcdefghjkmnpqrs",
7
+ "consent_url": "https://usefoil.com/gate?session=gate_0123456789abcdefghjkmnpqrs",
8
+ "expires_at": "2026-04-04T20:15:00.000Z"
9
+ },
10
+ "meta": {
11
+ "request_id": "req_0123456789abcdef0123456789abcdef"
12
+ }
13
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "data": {
3
+ "object": "gate_session",
4
+ "id": "gate_0123456789abcdefghjkmnpqrs",
5
+ "status": "approved",
6
+ "expires_at": "2026-04-04T20:15:00.000Z",
7
+ "gate_account_id": "gacct_0123456789abcdefghjkmnpqrs",
8
+ "account_name": "my-project",
9
+ "delivery_bundle": {
10
+ "integrator": {
11
+ "version": 1,
12
+ "algorithm": "x25519-hkdf-sha256/aes-256-gcm",
13
+ "key_id": "kid_integrator_0123456789abcdefgh",
14
+ "ephemeral_public_key": "ephemeral_public_key_integrator",
15
+ "salt": "salt_integrator",
16
+ "iv": "iv_integrator",
17
+ "ciphertext": "ciphertext_integrator",
18
+ "tag": "tag_integrator"
19
+ },
20
+ "gate": {
21
+ "version": 1,
22
+ "algorithm": "x25519-hkdf-sha256/aes-256-gcm",
23
+ "key_id": "kid_gate_0123456789abcdefghjkm",
24
+ "ephemeral_public_key": "ephemeral_public_key_gate",
25
+ "salt": "salt_gate",
26
+ "iv": "iv_gate",
27
+ "ciphertext": "ciphertext_gate",
28
+ "tag": "tag_gate"
29
+ }
30
+ },
31
+ "docs_url": "https://usefoil.com/docs/gate"
32
+ },
33
+ "meta": {
34
+ "request_id": "req_0123456789abcdef0123456789abcdef"
35
+ }
36
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "data": {
3
+ "object": "api_key",
4
+ "id": "key_2y4grs8zpxb7n1q3dm5kc9wfta",
5
+ "type": "secret",
6
+ "name": "Production Backend",
7
+ "environment": "live",
8
+ "status": "active",
9
+ "allowed_origins": null,
10
+ "scopes": [
11
+ "sessions:list",
12
+ "sessions:read",
13
+ "api_keys:read"
14
+ ],
15
+ "rate_limit": null,
16
+ "key_preview": "sk_live_[example]...",
17
+ "revealed_key": "sk_live_[example_secret_key]",
18
+ "last_used_at": null,
19
+ "created_at": "2026-03-24T19:00:00.000Z",
20
+ "rotated_at": null,
21
+ "revoked_at": null,
22
+ "grace_expires_at": null
23
+ },
24
+ "meta": {
25
+ "request_id": "req_0123456789abcdef0123456789abcdef"
26
+ }
27
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "data": [
3
+ {
4
+ "object": "api_key",
5
+ "id": "key_6789abcdefghjkmnpqrstvwxyz",
6
+ "type": "publishable",
7
+ "name": "Acme Web App",
8
+ "environment": "live",
9
+ "status": "active",
10
+ "allowed_origins": [
11
+ "https://example.com"
12
+ ],
13
+ "scopes": null,
14
+ "rate_limit": null,
15
+ "key_preview": "pk_live_[example]...",
16
+ "display_key": "pk_live_[example_publishable_key]",
17
+ "last_used_at": "2026-03-24T19:30:00.000Z",
18
+ "created_at": "2026-03-24T19:00:00.000Z",
19
+ "rotated_at": null,
20
+ "revoked_at": null,
21
+ "grace_expires_at": null
22
+ }
23
+ ],
24
+ "pagination": {
25
+ "limit": 50,
26
+ "has_more": false
27
+ },
28
+ "meta": {
29
+ "request_id": "req_0123456789abcdef0123456789abcdef"
30
+ }
31
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "data": {
3
+ "object": "api_key",
4
+ "id": "key_6789abcdefghjkmnpqrstvwxyz",
5
+ "type": "publishable",
6
+ "name": "Acme Web App",
7
+ "environment": "live",
8
+ "status": "revoked",
9
+ "allowed_origins": [
10
+ "https://example.com"
11
+ ],
12
+ "scopes": null,
13
+ "rate_limit": null,
14
+ "key_preview": "pk_live_[example]...",
15
+ "display_key": "pk_live_[example_publishable_key]",
16
+ "last_used_at": "2026-03-24T19:30:00.000Z",
17
+ "created_at": "2026-03-24T19:00:00.000Z",
18
+ "rotated_at": null,
19
+ "revoked_at": "2026-03-24T20:05:00.000Z",
20
+ "grace_expires_at": null
21
+ },
22
+ "meta": {
23
+ "request_id": "req_0123456789abcdef0123456789abcdef"
24
+ }
25
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "data": {
3
+ "object": "api_key",
4
+ "id": "key_789abcdefghjkmnpqrstvwxyz0",
5
+ "type": "secret",
6
+ "name": "Production Backend",
7
+ "environment": "live",
8
+ "status": "active",
9
+ "allowed_origins": null,
10
+ "scopes": [
11
+ "sessions:list",
12
+ "sessions:read",
13
+ "api_keys:manage"
14
+ ],
15
+ "rate_limit": null,
16
+ "key_preview": "sk_live_[rotated_example]...",
17
+ "revealed_key": "sk_live_[rotated_example_secret_key]",
18
+ "last_used_at": null,
19
+ "created_at": "2026-03-24T19:00:00.000Z",
20
+ "rotated_at": null,
21
+ "revoked_at": null,
22
+ "grace_expires_at": null
23
+ },
24
+ "meta": {
25
+ "request_id": "req_0123456789abcdef0123456789abcdef"
26
+ }
27
+ }