@sponson/adapters 0.0.0-stage → 0.5.0
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.
- package/LICENSE +202 -0
- package/README.md +4 -2
- package/dist/algolia.d.ts +6 -0
- package/dist/algolia.js +151 -0
- package/dist/algolia.js.map +1 -0
- package/dist/clerk.d.ts +8 -0
- package/dist/clerk.js +107 -0
- package/dist/clerk.js.map +1 -0
- package/dist/cloudflare.d.ts +25 -0
- package/dist/cloudflare.js +310 -0
- package/dist/cloudflare.js.map +1 -0
- package/dist/common.d.ts +73 -0
- package/dist/common.js +140 -0
- package/dist/common.js.map +1 -0
- package/dist/digest.d.ts +46 -0
- package/dist/digest.js +129 -0
- package/dist/digest.js.map +1 -0
- package/dist/digitalocean.d.ts +5 -0
- package/dist/digitalocean.js +243 -0
- package/dist/digitalocean.js.map +1 -0
- package/dist/http-adapter-action.d.ts +63 -0
- package/dist/http-adapter-action.js +369 -0
- package/dist/http-adapter-action.js.map +1 -0
- package/dist/http-adapter-auth.d.ts +88 -0
- package/dist/http-adapter-auth.js +437 -0
- package/dist/http-adapter-auth.js.map +1 -0
- package/dist/http-adapter-client.d.ts +51 -0
- package/dist/http-adapter-client.js +156 -0
- package/dist/http-adapter-client.js.map +1 -0
- package/dist/http-adapter-graphql.d.ts +39 -0
- package/dist/http-adapter-graphql.js +157 -0
- package/dist/http-adapter-graphql.js.map +1 -0
- package/dist/http-adapter-list.d.ts +33 -0
- package/dist/http-adapter-list.js +421 -0
- package/dist/http-adapter-list.js.map +1 -0
- package/dist/http-adapter-resource.d.ts +29 -0
- package/dist/http-adapter-resource.js +462 -0
- package/dist/http-adapter-resource.js.map +1 -0
- package/dist/http-adapter-spec.d.ts +216 -0
- package/dist/http-adapter-spec.js +660 -0
- package/dist/http-adapter-spec.js.map +1 -0
- package/dist/http-adapter.d.ts +16 -0
- package/dist/http-adapter.js +28 -0
- package/dist/http-adapter.js.map +1 -0
- package/dist/http.d.ts +179 -0
- package/dist/http.js +352 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/launchdarkly.d.ts +15 -0
- package/dist/launchdarkly.js +337 -0
- package/dist/launchdarkly.js.map +1 -0
- package/dist/manual.d.ts +13 -0
- package/dist/manual.js +201 -0
- package/dist/manual.js.map +1 -0
- package/dist/neon.d.ts +8 -0
- package/dist/neon.js +167 -0
- package/dist/neon.js.map +1 -0
- package/dist/netlify.d.ts +18 -0
- package/dist/netlify.js +436 -0
- package/dist/netlify.js.map +1 -0
- package/dist/planetscale.d.ts +10 -0
- package/dist/planetscale.js +311 -0
- package/dist/planetscale.js.map +1 -0
- package/dist/providers.d.ts +26 -0
- package/dist/providers.js +36 -0
- package/dist/providers.js.map +1 -0
- package/dist/recipes.d.ts +167 -0
- package/dist/recipes.js +246 -0
- package/dist/recipes.js.map +1 -0
- package/dist/secrets.d.ts +72 -0
- package/dist/secrets.js +476 -0
- package/dist/secrets.js.map +1 -0
- package/dist/sigv4.d.ts +56 -0
- package/dist/sigv4.js +118 -0
- package/dist/sigv4.js.map +1 -0
- package/dist/supabase.d.ts +9 -0
- package/dist/supabase.js +385 -0
- package/dist/supabase.js.map +1 -0
- package/dist/vercel.d.ts +8 -0
- package/dist/vercel.js +475 -0
- package/dist/vercel.js.map +1 -0
- package/dist/xata.d.ts +8 -0
- package/dist/xata.js +142 -0
- package/dist/xata.js.map +1 -0
- package/dist/xml.d.ts +25 -0
- package/dist/xml.js +211 -0
- package/dist/xml.js.map +1 -0
- package/package.json +58 -3
- package/recipes/amplify.yaml +147 -0
- package/recipes/auth0.yaml +178 -0
- package/recipes/azure_swa.yaml +116 -0
- package/recipes/cloud_run.yaml +97 -0
- package/recipes/cloudflare.yaml +108 -0
- package/recipes/cockroachdb.yaml +132 -0
- package/recipes/configcat.yaml +123 -0
- package/recipes/datadog.yaml +136 -0
- package/recipes/firebase.yaml +84 -0
- package/recipes/flagsmith.yaml +98 -0
- package/recipes/fly.yaml +97 -0
- package/recipes/fly_machines.yaml +67 -0
- package/recipes/gcs.yaml +102 -0
- package/recipes/github.yaml +123 -0
- package/recipes/growthbook.yaml +124 -0
- package/recipes/heroku.yaml +98 -0
- package/recipes/honeycomb.yaml +89 -0
- package/recipes/inngest.yaml +97 -0
- package/recipes/kinde.yaml +120 -0
- package/recipes/mongodb_atlas.yaml +119 -0
- package/recipes/okta.yaml +177 -0
- package/recipes/posthog.yaml +127 -0
- package/recipes/postmark.yaml +105 -0
- package/recipes/postmark_server.yaml +93 -0
- package/recipes/prisma.yaml +150 -0
- package/recipes/qstash.yaml +134 -0
- package/recipes/railway.yaml +130 -0
- package/recipes/render.yaml +103 -0
- package/recipes/resend.yaml +130 -0
- package/recipes/s3.yaml +108 -0
- package/recipes/sendgrid.yaml +165 -0
- package/recipes/sentry.yaml +158 -0
- package/recipes/split.yaml +121 -0
- package/recipes/statsig.yaml +124 -0
- package/recipes/stripe.yaml +310 -0
- package/recipes/stytch.yaml +113 -0
- package/recipes/svix.yaml +109 -0
- package/recipes/turso.yaml +98 -0
- package/recipes/unleash.yaml +149 -0
- package/recipes/upstash.yaml +130 -0
- package/recipes/vercel.yaml +116 -0
- package/recipes/workos.yaml +70 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# yaml-language-server: $schema=../../../schema/recipe.schema.json
|
|
2
|
+
# Kinde Management API recipes. Format and checklist: docs/adr/0020-recipes.md, CONTRIBUTING.md "Adding a recipe".
|
|
3
|
+
provider: kinde
|
|
4
|
+
title: Kinde
|
|
5
|
+
category: auth
|
|
6
|
+
verified_on: "2026-10-11"
|
|
7
|
+
docs:
|
|
8
|
+
- title: Kinde Management API (OpenAPI specification)
|
|
9
|
+
url: https://api-spec.kinde.com/kinde-management-api-spec.yaml
|
|
10
|
+
- title: Access the Kinde Management API
|
|
11
|
+
url: https://docs.kinde.com/developer-tools/kinde-api/connect-to-kinde-api/
|
|
12
|
+
- title: Kinde Management API JS SDK (conventional variable names)
|
|
13
|
+
url: https://github.com/kinde-oss/management-api-js
|
|
14
|
+
api:
|
|
15
|
+
base_url_env: KINDE_API_URL
|
|
16
|
+
auth:
|
|
17
|
+
oauth2_client_credentials:
|
|
18
|
+
token_url: /oauth2/token
|
|
19
|
+
token_url_env: KINDE_TOKEN_URL
|
|
20
|
+
client_id_env: KINDE_MANAGEMENT_CLIENT_ID
|
|
21
|
+
client_secret_env: KINDE_MANAGEMENT_CLIENT_SECRET
|
|
22
|
+
audience: /api
|
|
23
|
+
base_url_example: https://acme.kinde.com/api/v1
|
|
24
|
+
detect:
|
|
25
|
+
deps: ["@kinde-oss/"]
|
|
26
|
+
env: ["KINDE_*"]
|
|
27
|
+
starter:
|
|
28
|
+
- op: callback_url
|
|
29
|
+
- op: logout_url
|
|
30
|
+
preview_url: url
|
|
31
|
+
where:
|
|
32
|
+
base_url: "`https://<business>.kinde.com/api/v1`: Kinde → Settings → Details → Domain"
|
|
33
|
+
app_id: "Kinde → Settings → Applications → your application → Details → Client ID"
|
|
34
|
+
url: "the exact callback URL the SDK sends on a preview: its URL plus the callback path (a `{ from }` reference cannot carry a path)"
|
|
35
|
+
assumptions:
|
|
36
|
+
- id: KI1
|
|
37
|
+
verified: true
|
|
38
|
+
text: "A machine-to-machine application authorized for the Management API gets a token from `POST https://<business>.kinde.com/oauth2/token` (form-encoded `grant_type=client_credentials`, `client_id`, `client_secret`, `audience=https://<business>.kinde.com/api`); API calls go to `https://<business>.kinde.com/api/v1/…`. The recipe writes the token URL and audience as paths, so a plan's `base_url: https://<business>.kinde.com/api/v1` names the business once."
|
|
39
|
+
source: https://docs.kinde.com/developer-tools/kinde-api/connect-to-kinde-api/
|
|
40
|
+
- id: KI2
|
|
41
|
+
verified: true
|
|
42
|
+
text: "`GET /api/v1/applications/{app_id}/auth_redirect_urls` (scope `read:applications_redirect_uris`) answers `{ redirect_urls: [...] }`; `PUT` on the same path (scope `update:applications_redirect_uris`) replaces all of an application's callback URLs with the body's `urls` array. (`POST` adds and `DELETE ?urls=` removes; the recipe replaces the list it read, under a lock, so that one apply is one idempotent write.)"
|
|
43
|
+
source: https://api-spec.kinde.com/kinde-management-api-spec.yaml
|
|
44
|
+
- id: KI3
|
|
45
|
+
verified: true
|
|
46
|
+
text: "`GET /api/v1/applications/{app_id}/auth_logout_urls` answers `{ logout_urls: [...] }` and `PUT` replaces them with the body's `urls` array, as for callback URLs."
|
|
47
|
+
source: https://api-spec.kinde.com/kinde-management-api-spec.yaml
|
|
48
|
+
- id: KI4
|
|
49
|
+
verified: true
|
|
50
|
+
text: "The audience is always the business's kinde.com subdomain (`https://<business>.kinde.com/api`), even when a custom domain serves sign-in, so `base_url` names the kinde.com subdomain."
|
|
51
|
+
source: https://docs.kinde.com/developer-tools/kinde-api/connect-to-kinde-api/
|
|
52
|
+
- id: KI5
|
|
53
|
+
verified: true
|
|
54
|
+
text: "`KINDE_MANAGEMENT_CLIENT_ID` and `KINDE_MANAGEMENT_CLIENT_SECRET` are the variables Kinde's Management API SDK reads for the machine-to-machine client."
|
|
55
|
+
source: https://github.com/kinde-oss/management-api-js
|
|
56
|
+
- id: KI6
|
|
57
|
+
verified: false
|
|
58
|
+
text: "A `PUT` with an empty `urls` list is accepted and leaves the application with no URLs of that kind (destroying the last preview URL of an application that has no others)."
|
|
59
|
+
- id: KI7
|
|
60
|
+
verified: false
|
|
61
|
+
text: "URLs are read back exactly as written (no normalisation), and the replace has no precondition: the line locks the list (`lockOn`) against other Sponson runs; a console edit made between the read and the write can still be lost."
|
|
62
|
+
ops:
|
|
63
|
+
callback_url:
|
|
64
|
+
kind: list_item
|
|
65
|
+
title: Application callback URL
|
|
66
|
+
summary: "One URL in a Kinde application's Allowed callback URLs, such as the preview's `/api/auth/kinde_callback`. Read-modify-write: the list is read (`redirect_urls`) and replaced (`urls`) with the URL added, under a lock on the list; removed on destroy; every other URL is left as it is."
|
|
67
|
+
covers: [kinde-callbacks]
|
|
68
|
+
params:
|
|
69
|
+
app_id:
|
|
70
|
+
type: string
|
|
71
|
+
required: true
|
|
72
|
+
description: The application's id (its Client ID in the Kinde dashboard).
|
|
73
|
+
example: 3b0b5c6c8fcc464fab397f4969b5f482
|
|
74
|
+
url:
|
|
75
|
+
type: string
|
|
76
|
+
required: true
|
|
77
|
+
pattern: "^https?://\\S+$"
|
|
78
|
+
description: "The callback URL, exactly as the SDK sends it (`KINDE_REDIRECT_URL` / `KINDE_SITE_URL` + the callback path)."
|
|
79
|
+
example: "https://${ctx.scope}.preview.example.app/api/auth/kinde_callback"
|
|
80
|
+
http:
|
|
81
|
+
parent:
|
|
82
|
+
path: "/applications/{app_id}/auth_redirect_urls"
|
|
83
|
+
method: PUT
|
|
84
|
+
write_list_path: /urls
|
|
85
|
+
list_path: /redirect_urls
|
|
86
|
+
item: { param: url }
|
|
87
|
+
sim:
|
|
88
|
+
objects:
|
|
89
|
+
"/applications/{app_id}/auth_redirect_urls": { redirect_urls: [https://app.example.com/api/auth/kinde_callback] }
|
|
90
|
+
live:
|
|
91
|
+
params: { app_id: SPONSON_LIVE_KINDE_APP_ID }
|
|
92
|
+
logout_url:
|
|
93
|
+
kind: list_item
|
|
94
|
+
title: Application allowed logout redirect URL
|
|
95
|
+
summary: "One URL in a Kinde application's Allowed logout redirect URLs, such as the preview's home page. Read (`logout_urls`) and replaced (`urls`) with the URL added, under a lock on the list; removed on destroy; every other URL is left as it is."
|
|
96
|
+
covers: [kinde-callbacks]
|
|
97
|
+
params:
|
|
98
|
+
app_id:
|
|
99
|
+
type: string
|
|
100
|
+
required: true
|
|
101
|
+
description: The application's id (its Client ID in the Kinde dashboard).
|
|
102
|
+
example: 3b0b5c6c8fcc464fab397f4969b5f482
|
|
103
|
+
url:
|
|
104
|
+
type: string
|
|
105
|
+
required: true
|
|
106
|
+
pattern: "^https?://\\S+$"
|
|
107
|
+
description: "The URL the SDK redirects to after logout (`KINDE_POST_LOGOUT_REDIRECT_URL`)."
|
|
108
|
+
example: "https://${ctx.scope}.preview.example.app"
|
|
109
|
+
http:
|
|
110
|
+
parent:
|
|
111
|
+
path: "/applications/{app_id}/auth_logout_urls"
|
|
112
|
+
method: PUT
|
|
113
|
+
write_list_path: /urls
|
|
114
|
+
list_path: /logout_urls
|
|
115
|
+
item: { param: url }
|
|
116
|
+
sim:
|
|
117
|
+
objects:
|
|
118
|
+
"/applications/{app_id}/auth_logout_urls": { logout_urls: [https://app.example.com] }
|
|
119
|
+
live:
|
|
120
|
+
params: { app_id: SPONSON_LIVE_KINDE_APP_ID }
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# yaml-language-server: $schema=../../../schema/recipe.schema.json
|
|
2
|
+
# MongoDB Atlas Administration API v2 recipes (programmatic API keys, HTTP Digest). Format and checklist:
|
|
3
|
+
# docs/adr/0020-recipes.md, CONTRIBUTING.md "Adding a recipe".
|
|
4
|
+
provider: mongodb_atlas
|
|
5
|
+
title: MongoDB Atlas
|
|
6
|
+
category: databases
|
|
7
|
+
verified_on: "2026-10-11"
|
|
8
|
+
docs:
|
|
9
|
+
- title: Atlas Administration API v2 (OpenAPI document)
|
|
10
|
+
url: https://www.mongodb.com/docs/api/doc/atlas-admin-api-v2.json
|
|
11
|
+
- title: Create One Database User in One Project
|
|
12
|
+
url: https://www.mongodb.com/docs/api/doc/atlas-admin-api-v2/operation/operation-creategroupdatabaseuser
|
|
13
|
+
- title: Configure Atlas API access (API keys use HTTP Digest)
|
|
14
|
+
url: https://www.mongodb.com/docs/atlas/configure-api-access/
|
|
15
|
+
- title: Atlas CLI environment variables
|
|
16
|
+
url: https://www.mongodb.com/docs/atlas/cli/current/atlas-cli-env-variables/
|
|
17
|
+
api:
|
|
18
|
+
base_url: https://cloud.mongodb.com/api/atlas/v2
|
|
19
|
+
base_url_env: MONGODB_ATLAS_API_URL
|
|
20
|
+
media_type: application/vnd.atlas.2023-01-01+json
|
|
21
|
+
auth: { digest: { user_env: MONGODB_ATLAS_PUBLIC_API_KEY, password_env: MONGODB_ATLAS_PRIVATE_API_KEY } }
|
|
22
|
+
detect:
|
|
23
|
+
env: ["MONGODB_ATLAS_*"]
|
|
24
|
+
db_hosts: [.mongodb.net]
|
|
25
|
+
starter:
|
|
26
|
+
- op: database_user
|
|
27
|
+
values: { username: "app-${ctx.scope}", roles: [{ databaseName: "app_${ctx.scope}", roleName: readWrite }] }
|
|
28
|
+
where:
|
|
29
|
+
group_id: "Atlas → Project Settings → Project ID, or `atlas projects list`"
|
|
30
|
+
password: "a reference, never a value: `{ secret: \"env://PREVIEW_DB_PASSWORD\" }`"
|
|
31
|
+
assumptions:
|
|
32
|
+
- id: MA1
|
|
33
|
+
verified: true
|
|
34
|
+
text: "Programmatic API keys authenticate with HTTP Digest (the public key as the user name, the private key as the password); service accounts take an OAuth2 client-credentials token instead (`https://cloud.mongodb.com/api/oauth/token`)."
|
|
35
|
+
source: https://www.mongodb.com/docs/atlas/configure-api-access/
|
|
36
|
+
- id: MA2
|
|
37
|
+
verified: true
|
|
38
|
+
text: "The Atlas CLI keeps the key pair in `MONGODB_ATLAS_PUBLIC_API_KEY` and `MONGODB_ATLAS_PRIVATE_API_KEY`."
|
|
39
|
+
source: https://www.mongodb.com/docs/atlas/cli/current/atlas-cli-env-variables/
|
|
40
|
+
- id: MA3
|
|
41
|
+
verified: true
|
|
42
|
+
text: "Requests and answers use the versioned media type `application/vnd.atlas.2023-01-01+json` (in `Accept` and `Content-Type`); the database-user operations are published under that version."
|
|
43
|
+
source: https://www.mongodb.com/docs/api/doc/atlas-admin-api-v2.json
|
|
44
|
+
- id: MA4
|
|
45
|
+
verified: true
|
|
46
|
+
text: "`POST /groups/{groupId}/databaseUsers` creates a user from `databaseName`, `groupId`, `roles` and `username` (required), with `password` for SCRAM users (write-only, never answered), optional `scopes` (absent: every cluster of the project) and `deleteAfterDate` (Atlas deletes the user then; within one week of the request). It answers 201 with the user."
|
|
47
|
+
source: https://www.mongodb.com/docs/api/doc/atlas-admin-api-v2.json
|
|
48
|
+
- id: MA5
|
|
49
|
+
verified: true
|
|
50
|
+
text: "`GET`, `PATCH` and `DELETE /groups/{groupId}/databaseUsers/{databaseName}/{username}` read, update and delete one user; SCRAM users authenticate against `databaseName` `admin`."
|
|
51
|
+
source: https://www.mongodb.com/docs/api/doc/atlas-admin-api-v2.json
|
|
52
|
+
- id: MA6
|
|
53
|
+
verified: true
|
|
54
|
+
text: "A project supports 100 database users by default (900 at most)."
|
|
55
|
+
source: https://www.mongodb.com/docs/api/doc/atlas-admin-api-v2/operation/operation-creategroupdatabaseuser
|
|
56
|
+
- id: MA7
|
|
57
|
+
verified: false
|
|
58
|
+
text: "A GET of a user that does not exist answers 404; a second create of the same user answers 409."
|
|
59
|
+
- id: MA8
|
|
60
|
+
verified: false
|
|
61
|
+
text: "`roles` (each `{ databaseName, roleName, collectionName? }`) and `scopes` (each `{ name, type }`) are answered in the order they were sent, so they compare without drift."
|
|
62
|
+
- id: MA9
|
|
63
|
+
verified: false
|
|
64
|
+
text: "`PATCH` takes the user's identifying fields (`databaseName`, `groupId`, `username`) with the changed ones and keeps the password when none is sent."
|
|
65
|
+
ops:
|
|
66
|
+
database_user:
|
|
67
|
+
kind: resource
|
|
68
|
+
title: Database user
|
|
69
|
+
summary: "A SCRAM database user per scope on a shared Atlas cluster, such as `app-pr-42` with `readWrite` on the database `app_pr_42`, instead of a cluster per preview. The password is an input: a `{ secret: … }` reference (a value per environment in a secret manager) or a sensitive output of another line, sent on create only and never compared. Located by its user name; a console edit of its roles or scopes is drift; destroy deletes the user (not the database's data)."
|
|
70
|
+
covers: [mongodb-atlas-user]
|
|
71
|
+
params:
|
|
72
|
+
group_id:
|
|
73
|
+
type: string
|
|
74
|
+
required: true
|
|
75
|
+
pattern: "^[0-9a-f]{24}$"
|
|
76
|
+
description: The project (group) id, 24 hexadecimal digits.
|
|
77
|
+
example: 32b6e34b3d91647abb20e7b8
|
|
78
|
+
username:
|
|
79
|
+
type: string
|
|
80
|
+
required: true
|
|
81
|
+
description: The user name, unique in the project; its identity.
|
|
82
|
+
example: "app-${ctx.scope}"
|
|
83
|
+
password:
|
|
84
|
+
type: string
|
|
85
|
+
required: true
|
|
86
|
+
description: "The user's password, as a reference (`{ secret: env://… }`, or `{ from: <line>.<output> }` of a sensitive output); sent on create only (MA4)."
|
|
87
|
+
example: { secret: "env://PREVIEW_DB_PASSWORD" }
|
|
88
|
+
roles:
|
|
89
|
+
type: list
|
|
90
|
+
required: true
|
|
91
|
+
description: "The roles, each `{ databaseName, roleName }` (`readWrite`, `read`, `dbAdmin`, …)."
|
|
92
|
+
example: [{ databaseName: "app_${ctx.scope}", roleName: readWrite }]
|
|
93
|
+
scopes:
|
|
94
|
+
type: list
|
|
95
|
+
description: "The clusters it may reach, each `{ name, type: CLUSTER }`; absent: every cluster of the project (not compared then)."
|
|
96
|
+
delete_after:
|
|
97
|
+
type: string
|
|
98
|
+
description: "An ISO 8601 time, within a week, at which Atlas deletes the user by itself (sent on create only)."
|
|
99
|
+
http:
|
|
100
|
+
read: { path: "/groups/{group_id}/databaseUsers/admin/{username}" }
|
|
101
|
+
create:
|
|
102
|
+
path: "/groups/{group_id}/databaseUsers"
|
|
103
|
+
body:
|
|
104
|
+
databaseName: admin
|
|
105
|
+
groupId: { param: group_id }
|
|
106
|
+
username: { param: username }
|
|
107
|
+
password: { param: password }
|
|
108
|
+
deleteAfterDate: { param: delete_after }
|
|
109
|
+
update:
|
|
110
|
+
method: PATCH
|
|
111
|
+
body: { databaseName: admin, groupId: { param: group_id }, username: { param: username } }
|
|
112
|
+
id_path: /username
|
|
113
|
+
fields:
|
|
114
|
+
roles: { param: roles }
|
|
115
|
+
scopes: { param: scopes }
|
|
116
|
+
sim:
|
|
117
|
+
id_from: username
|
|
118
|
+
live:
|
|
119
|
+
params: { group_id: SPONSON_LIVE_ATLAS_GROUP_ID }
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# yaml-language-server: $schema=../../../schema/recipe.schema.json
|
|
2
|
+
# Okta Management API recipes. Format and checklist: docs/adr/0020-recipes.md, CONTRIBUTING.md "Adding a recipe".
|
|
3
|
+
provider: okta
|
|
4
|
+
title: Okta
|
|
5
|
+
category: auth
|
|
6
|
+
verified_on: "2026-10-11"
|
|
7
|
+
docs:
|
|
8
|
+
- title: Okta Management API (OpenAPI specification, management-minimal.yaml)
|
|
9
|
+
url: https://raw.githubusercontent.com/okta/okta-management-openapi-spec/master/dist/current/management-minimal.yaml
|
|
10
|
+
- title: Applications API, replace an application
|
|
11
|
+
url: https://developer.okta.com/docs/api/openapi/okta-management/management/tag/Application/#tag/Application/operation/replaceApplication
|
|
12
|
+
- title: Trusted Origins API
|
|
13
|
+
url: https://developer.okta.com/docs/api/openapi/okta-management/management/tag/TrustedOrigin/
|
|
14
|
+
- title: Okta Terraform provider, configuration (conventional variable names)
|
|
15
|
+
url: https://raw.githubusercontent.com/okta/terraform-provider-okta/master/docs/index.md
|
|
16
|
+
api:
|
|
17
|
+
base_url_env: OKTA_API_URL
|
|
18
|
+
auth: { header: Authorization, value_env: OKTA_API_TOKEN, prefix: "SSWS " }
|
|
19
|
+
base_url_example: https://acme.okta.com/api/v1
|
|
20
|
+
detect:
|
|
21
|
+
deps: ["@okta/"]
|
|
22
|
+
env: ["OKTA_*"]
|
|
23
|
+
starter:
|
|
24
|
+
- op: redirect_uri
|
|
25
|
+
- op: trusted_origin
|
|
26
|
+
preview_url: origin
|
|
27
|
+
values: { name: "sponson-${ctx.scope}" }
|
|
28
|
+
where:
|
|
29
|
+
base_url: "`https://<org>.okta.com/api/v1`: your Okta org's domain"
|
|
30
|
+
app_id: "Okta Admin Console → Applications → your application: the `0oa…` id in its URL"
|
|
31
|
+
url: "the exact redirect URI the app sends on a preview: its URL plus the callback path (a `{ from }` reference cannot carry a path)"
|
|
32
|
+
assumptions:
|
|
33
|
+
- id: OK1
|
|
34
|
+
verified: true
|
|
35
|
+
text: "An API token is sent as `Authorization: SSWS <token>` (the `apiToken` security scheme; Okta recommends scoped OAuth tokens, which need `private_key_jwt` and are not supported here). Every path is under `https://<org>.okta.com/api/v1`."
|
|
36
|
+
source: https://raw.githubusercontent.com/okta/okta-management-openapi-spec/master/dist/current/management-minimal.yaml
|
|
37
|
+
- id: OK2
|
|
38
|
+
verified: true
|
|
39
|
+
text: "`PUT /api/v1/apps/{appId}` replaces an application: all required properties must be in the body (no partial update), and system-assigned properties (`id`, `name`, `status`, `created`, `lastUpdated`) in the body are ignored. So the recipe sends the whole application read with `GET /api/v1/apps/{appId}` back, with one URI added or removed (`parent.send: parent`)."
|
|
40
|
+
source: https://raw.githubusercontent.com/okta/okta-management-openapi-spec/master/dist/current/management-minimal.yaml
|
|
41
|
+
- id: OK3
|
|
42
|
+
verified: true
|
|
43
|
+
text: "An OIDC application keeps its redirect URIs in `settings.oauthClient.redirect_uris` and its sign-out redirect URIs in `settings.oauthClient.post_logout_redirect_uris`, both arrays of strings."
|
|
44
|
+
source: https://raw.githubusercontent.com/okta/okta-management-openapi-spec/master/dist/current/management-minimal.yaml
|
|
45
|
+
- id: OK4
|
|
46
|
+
verified: false
|
|
47
|
+
text: "The read-only members of the GET answer that the replace documentation does not list (`_links`, `_embedded`, `credentials.oauthClient.client_id`) are ignored when sent back, as the listed system-assigned ones are."
|
|
48
|
+
- id: OK5
|
|
49
|
+
verified: false
|
|
50
|
+
text: "The application replace has no precondition: the line locks the application (`lockOn`, shared by both URI ops) against other Sponson runs; a console edit made between the read and the write can still be lost (the next apply reports it as drift)."
|
|
51
|
+
- id: OK6
|
|
52
|
+
verified: true
|
|
53
|
+
text: "`POST /api/v1/trustedOrigins` creates a trusted origin from `name`, `origin` and `scopes` (`[{ type: CORS }, { type: REDIRECT }]`, or `IFRAME_EMBED`); `GET /api/v1/trustedOrigins` lists them as a bare array, `q` prefix-matching `name` and `origin`, `limit` up to 200; `PUT /api/v1/trustedOrigins/{id}` replaces one; `DELETE /api/v1/trustedOrigins/{id}` answers 204. `name` and `origin` are each unique."
|
|
54
|
+
source: https://raw.githubusercontent.com/okta/okta-management-openapi-spec/master/dist/current/management-minimal.yaml
|
|
55
|
+
- id: OK7
|
|
56
|
+
verified: false
|
|
57
|
+
text: "A trusted origin is found among the first 200 that `q=<origin>` matches (pagination follows a `Link` header, which the http adapter does not read); an org with more than 200 origins starting with the same text may not find it and would see the create refused as a duplicate."
|
|
58
|
+
- id: OK8
|
|
59
|
+
verified: false
|
|
60
|
+
text: "Scopes are read back as written (`[{ type: CORS }, { type: REDIRECT }]`, no added members), so they can be compared as drift."
|
|
61
|
+
- id: OK9
|
|
62
|
+
verified: true
|
|
63
|
+
text: "`OKTA_API_TOKEN` is the variable the Okta Terraform provider reads for an API token."
|
|
64
|
+
source: https://raw.githubusercontent.com/okta/terraform-provider-okta/master/docs/index.md
|
|
65
|
+
ops:
|
|
66
|
+
redirect_uri:
|
|
67
|
+
kind: list_item
|
|
68
|
+
title: OIDC application sign-in redirect URI
|
|
69
|
+
summary: "One URI in an Okta OIDC application's sign-in redirect URIs (`settings.oauthClient.redirect_uris`), such as the preview's `/login/callback`. The application is read, and written back whole with the URI added (Okta replaces applications only as a whole), under a lock on the application; removed on destroy; every other URI and setting is sent back as read."
|
|
70
|
+
covers: [okta-redirect]
|
|
71
|
+
params:
|
|
72
|
+
app_id:
|
|
73
|
+
type: string
|
|
74
|
+
required: true
|
|
75
|
+
description: The application's id (`0oa…`).
|
|
76
|
+
example: 0oa1gjh63g214q0Hq0g4
|
|
77
|
+
url:
|
|
78
|
+
type: string
|
|
79
|
+
required: true
|
|
80
|
+
pattern: "^\\S+://\\S+$"
|
|
81
|
+
description: "The redirect URI, exactly as the application sends it as `redirect_uri`."
|
|
82
|
+
example: "https://${ctx.scope}.preview.example.app/login/callback"
|
|
83
|
+
http:
|
|
84
|
+
parent: { path: "/apps/{app_id}", method: PUT, send: parent }
|
|
85
|
+
list_path: /settings/oauthClient/redirect_uris
|
|
86
|
+
item: { param: url }
|
|
87
|
+
sim:
|
|
88
|
+
objects:
|
|
89
|
+
"/apps/{app_id}":
|
|
90
|
+
id: 0oa1gjh63g214q0Hq0g4
|
|
91
|
+
name: oidc_client
|
|
92
|
+
label: Web app
|
|
93
|
+
status: ACTIVE
|
|
94
|
+
signOnMode: OPENID_CONNECT
|
|
95
|
+
credentials: { oauthClient: { client_id: 0oa1gjh63g214q0Hq0g4, token_endpoint_auth_method: client_secret_basic } }
|
|
96
|
+
settings:
|
|
97
|
+
oauthClient:
|
|
98
|
+
application_type: web
|
|
99
|
+
grant_types: [authorization_code]
|
|
100
|
+
response_types: [code]
|
|
101
|
+
redirect_uris: [https://app.example.com/login/callback]
|
|
102
|
+
post_logout_redirect_uris: [https://app.example.com]
|
|
103
|
+
live:
|
|
104
|
+
params: { app_id: SPONSON_LIVE_OKTA_APP_ID }
|
|
105
|
+
post_logout_redirect_uri:
|
|
106
|
+
kind: list_item
|
|
107
|
+
title: OIDC application sign-out redirect URI
|
|
108
|
+
summary: "One URI in an Okta OIDC application's sign-out redirect URIs (`settings.oauthClient.post_logout_redirect_uris`), such as the preview's home page. Written back with the whole application, under the application's lock; removed on destroy; every other URI and setting is sent back as read."
|
|
109
|
+
covers: [okta-redirect]
|
|
110
|
+
params:
|
|
111
|
+
app_id:
|
|
112
|
+
type: string
|
|
113
|
+
required: true
|
|
114
|
+
description: The application's id (`0oa…`).
|
|
115
|
+
example: 0oa1gjh63g214q0Hq0g4
|
|
116
|
+
url:
|
|
117
|
+
type: string
|
|
118
|
+
required: true
|
|
119
|
+
pattern: "^\\S+://\\S+$"
|
|
120
|
+
description: "The URI the application passes as `post_logout_redirect_uri`."
|
|
121
|
+
example: "https://${ctx.scope}.preview.example.app"
|
|
122
|
+
http:
|
|
123
|
+
parent: { path: "/apps/{app_id}", method: PUT, send: parent }
|
|
124
|
+
list_path: /settings/oauthClient/post_logout_redirect_uris
|
|
125
|
+
item: { param: url }
|
|
126
|
+
sim:
|
|
127
|
+
objects:
|
|
128
|
+
"/apps/{app_id}":
|
|
129
|
+
id: 0oa1gjh63g214q0Hq0g4
|
|
130
|
+
name: oidc_client
|
|
131
|
+
label: Web app
|
|
132
|
+
status: ACTIVE
|
|
133
|
+
signOnMode: OPENID_CONNECT
|
|
134
|
+
credentials: { oauthClient: { client_id: 0oa1gjh63g214q0Hq0g4, token_endpoint_auth_method: client_secret_basic } }
|
|
135
|
+
settings:
|
|
136
|
+
oauthClient:
|
|
137
|
+
application_type: web
|
|
138
|
+
grant_types: [authorization_code]
|
|
139
|
+
response_types: [code]
|
|
140
|
+
redirect_uris: [https://app.example.com/login/callback]
|
|
141
|
+
post_logout_redirect_uris: [https://app.example.com]
|
|
142
|
+
live:
|
|
143
|
+
params: { app_id: SPONSON_LIVE_OKTA_APP_ID }
|
|
144
|
+
trusted_origin:
|
|
145
|
+
kind: resource
|
|
146
|
+
title: Trusted origin (CORS and redirect)
|
|
147
|
+
summary: "A trusted origin for the preview, so the Okta Sign-In Widget and Auth JS may call Okta from it (CORS) and Okta may redirect to it after sign-in or sign-out (REDIRECT). Found by its origin; its name and scopes are compared as drift and replaced with `PUT`; deleted on destroy."
|
|
148
|
+
covers: [okta-redirect]
|
|
149
|
+
params:
|
|
150
|
+
name:
|
|
151
|
+
type: string
|
|
152
|
+
required: true
|
|
153
|
+
description: "The trusted origin's name, unique in the org."
|
|
154
|
+
example: "sponson-${ctx.scope}"
|
|
155
|
+
origin:
|
|
156
|
+
type: string
|
|
157
|
+
required: true
|
|
158
|
+
pattern: "^\\S+://[^/\\s]+$"
|
|
159
|
+
description: "The origin, scheme and host without a path (`https://pr-42.preview.example.app`); unique in the org."
|
|
160
|
+
example: "https://${ctx.scope}.preview.example.app"
|
|
161
|
+
scopes:
|
|
162
|
+
type: list
|
|
163
|
+
default: [{ type: CORS }, { type: REDIRECT }]
|
|
164
|
+
description: "What the origin is trusted for: `[{ type: CORS }]`, `[{ type: REDIRECT }]`, both (the default), or `IFRAME_EMBED`."
|
|
165
|
+
http:
|
|
166
|
+
find:
|
|
167
|
+
path: "/trustedOrigins?q={origin}&limit=200"
|
|
168
|
+
list_path: ""
|
|
169
|
+
match: { origin: { param: origin } }
|
|
170
|
+
create: { path: /trustedOrigins }
|
|
171
|
+
update: { method: PUT, path: "/trustedOrigins/{id}" }
|
|
172
|
+
delete: { path: "/trustedOrigins/{id}" }
|
|
173
|
+
item_path: ""
|
|
174
|
+
fields:
|
|
175
|
+
name: { param: name }
|
|
176
|
+
origin: { param: origin }
|
|
177
|
+
scopes: { param: scopes }
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# yaml-language-server: $schema=../../../schema/recipe.schema.json
|
|
2
|
+
# PostHog private API recipes. Format and checklist: docs/adr/0020-recipes.md, CONTRIBUTING.md "Adding a recipe".
|
|
3
|
+
provider: posthog
|
|
4
|
+
title: PostHog
|
|
5
|
+
category: flags
|
|
6
|
+
verified_on: "2026-10-11"
|
|
7
|
+
docs:
|
|
8
|
+
- title: Private API (hosts, personal API keys)
|
|
9
|
+
url: https://posthog.com/docs/api
|
|
10
|
+
- title: Feature flags API
|
|
11
|
+
url: https://posthog.com/docs/api/feature-flags
|
|
12
|
+
- title: OpenAPI schema (FeatureFlag, PersonalAPIKeyAuth)
|
|
13
|
+
url: https://us.posthog.com/api/schema/?format=json
|
|
14
|
+
- title: Feature flag serializer (filters validation and merge)
|
|
15
|
+
url: https://github.com/PostHog/posthog/blob/master/products/feature_flags/backend/api/feature_flag.py
|
|
16
|
+
- title: Feature flag filters schema (condition groups)
|
|
17
|
+
url: https://github.com/PostHog/posthog/blob/master/products/feature_flags/backend/api/filters_schema.py
|
|
18
|
+
api:
|
|
19
|
+
base_url: https://us.posthog.com
|
|
20
|
+
base_url_env: POSTHOG_API_URL
|
|
21
|
+
auth: { bearer_env: POSTHOG_PERSONAL_API_KEY }
|
|
22
|
+
detect:
|
|
23
|
+
deps: [posthog-js, posthog-node, posthog-react-native]
|
|
24
|
+
env: ["POSTHOG_*"]
|
|
25
|
+
starter:
|
|
26
|
+
- op: release_condition
|
|
27
|
+
values: { property: $host }
|
|
28
|
+
where:
|
|
29
|
+
project_id: "PostHog → Settings → Project → Project ID"
|
|
30
|
+
flag_id: "PostHog → Feature flags → your flag: the number in its URL"
|
|
31
|
+
value: "the preview's host name (with `property: $host`)"
|
|
32
|
+
assumptions:
|
|
33
|
+
- id: PH1
|
|
34
|
+
verified: true
|
|
35
|
+
text: "The private API is at `https://us.posthog.com` (US cloud) or `https://eu.posthog.com` (EU cloud; set `base_url`), authenticated with a personal API key as `Authorization: Bearer`, with the `feature_flag:read` and `feature_flag:write` scopes."
|
|
36
|
+
source: https://posthog.com/docs/api
|
|
37
|
+
- id: PH2
|
|
38
|
+
verified: true
|
|
39
|
+
text: "`GET /api/projects/{project_id}/feature_flags/{id}/` (trailing slash) answers the flag bare, with its release conditions in `filters.groups`; `PATCH` on the same path updates it and answers it bare."
|
|
40
|
+
source: https://us.posthog.com/api/schema/?format=json
|
|
41
|
+
- id: PH3
|
|
42
|
+
verified: true
|
|
43
|
+
text: "A condition group is `{ properties: [{ key, type, operator, value }], rollout_percentage, variant }`; `exact` takes a list of values. Groups have no id, so the group is identified by the first value of its first property (the preview host)."
|
|
44
|
+
source: https://github.com/PostHog/posthog/blob/master/products/feature_flags/backend/api/filters_schema.py
|
|
45
|
+
- id: PH4
|
|
46
|
+
verified: true
|
|
47
|
+
text: "A PATCH of `filters` merges top-level keys into the stored filters (`{**stored_filters, **filters}`): sending `{ filters: { groups } }` replaces the groups and keeps `multivariate`, `payloads` and the rest. This is in the serializer's source, not the docs."
|
|
48
|
+
source: https://github.com/PostHog/posthog/blob/master/products/feature_flags/backend/api/feature_flag.py
|
|
49
|
+
- id: PH5
|
|
50
|
+
verified: false
|
|
51
|
+
text: "Self-hosted or older PostHog versions merge `filters` the same way (the merge arrived with 2026's validation work). On a version that replaces `filters` whole, every write would drop the flag's variants and payloads: check before pointing the recipe at one."
|
|
52
|
+
- id: PH6
|
|
53
|
+
verified: false
|
|
54
|
+
text: "A group is read back as written (the serializer drops unknown keys and adds none to the declared ones), so the compared `properties`, `rollout_percentage` and `variant` do not show as changed on every plan."
|
|
55
|
+
- id: PH7
|
|
56
|
+
verified: true
|
|
57
|
+
text: "A flag under an approval policy answers a PATCH with 409 (`approval_required` or `change_request_pending`); the apply then fails with PROVIDER_CONFLICT rather than waiting for the approval."
|
|
58
|
+
source: https://github.com/PostHog/posthog/blob/master/products/approvals/backend/decorators.py
|
|
59
|
+
ops:
|
|
60
|
+
release_condition:
|
|
61
|
+
kind: list_item
|
|
62
|
+
title: Flag release condition
|
|
63
|
+
summary: "A release condition (condition group) on an existing feature flag that matches the preview, such as `$host exact [pr-42.preview.example.com]` at 100%. Groups are OR'd; the flag's other groups, variants and payloads are left as they are. A console edit of its properties, rollout or variant is drift. Destroy removes the group (with the last group gone, the flag matches no one)."
|
|
64
|
+
covers: [posthog-release-condition]
|
|
65
|
+
params:
|
|
66
|
+
project_id:
|
|
67
|
+
type: string
|
|
68
|
+
required: true
|
|
69
|
+
pattern: "^[0-9]+$"
|
|
70
|
+
description: The project's numeric id (Project settings).
|
|
71
|
+
example: "12345"
|
|
72
|
+
flag_id:
|
|
73
|
+
type: string
|
|
74
|
+
required: true
|
|
75
|
+
pattern: "^[0-9]+$"
|
|
76
|
+
description: The flag's numeric id (in the flag's URL), not its key.
|
|
77
|
+
example: "678"
|
|
78
|
+
property:
|
|
79
|
+
type: string
|
|
80
|
+
required: true
|
|
81
|
+
description: The property the condition tests. It must be known when the flag is evaluated (a person property, or one passed with the evaluation).
|
|
82
|
+
example: $host
|
|
83
|
+
property_type:
|
|
84
|
+
type: string
|
|
85
|
+
default: person
|
|
86
|
+
enum: [person, group]
|
|
87
|
+
description: Whether `property` is a person or a group property.
|
|
88
|
+
operator:
|
|
89
|
+
type: string
|
|
90
|
+
default: exact
|
|
91
|
+
enum: [exact, is_not, icontains, regex]
|
|
92
|
+
description: How the property is compared with `value`.
|
|
93
|
+
value:
|
|
94
|
+
type: string
|
|
95
|
+
required: true
|
|
96
|
+
description: The value that matches the preview (such as its host); it identifies the condition on the flag.
|
|
97
|
+
example: "${ctx.scope}.preview.example.com"
|
|
98
|
+
rollout_percentage:
|
|
99
|
+
type: integer
|
|
100
|
+
default: 100
|
|
101
|
+
description: The share of matching users the flag is on for (0–100).
|
|
102
|
+
variant:
|
|
103
|
+
type: string
|
|
104
|
+
description: For a multivariate flag, the variant the condition serves.
|
|
105
|
+
http:
|
|
106
|
+
parent: { path: "/api/projects/{project_id}/feature_flags/{flag_id}/", method: PATCH }
|
|
107
|
+
list_path: /filters/groups
|
|
108
|
+
key_field: /properties/0/value/0
|
|
109
|
+
item:
|
|
110
|
+
properties:
|
|
111
|
+
- key: { param: property }
|
|
112
|
+
type: { param: property_type }
|
|
113
|
+
operator: { param: operator }
|
|
114
|
+
value: [{ param: value }]
|
|
115
|
+
rollout_percentage: { param: rollout_percentage }
|
|
116
|
+
variant: { param: variant }
|
|
117
|
+
sim:
|
|
118
|
+
objects:
|
|
119
|
+
"/api/projects/{project_id}/feature_flags/{flag_id}":
|
|
120
|
+
id: 678
|
|
121
|
+
key: new-checkout
|
|
122
|
+
filters:
|
|
123
|
+
groups: [{ properties: [], rollout_percentage: 0 }]
|
|
124
|
+
multivariate: null
|
|
125
|
+
payloads: {}
|
|
126
|
+
live:
|
|
127
|
+
params: { project_id: SPONSON_LIVE_POSTHOG_PROJECT_ID, flag_id: SPONSON_LIVE_POSTHOG_FLAG_ID }
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# yaml-language-server: $schema=../../../schema/recipe.schema.json
|
|
2
|
+
# Postmark Account API recipes (account token). The Server API, which takes a server's own token, is
|
|
3
|
+
# postmark_server.yaml. Format and checklist: docs/adr/0020-recipes.md, CONTRIBUTING.md "Adding a recipe".
|
|
4
|
+
provider: postmark
|
|
5
|
+
title: Postmark (Account API)
|
|
6
|
+
category: email
|
|
7
|
+
verified_on: "2026-10-11"
|
|
8
|
+
docs:
|
|
9
|
+
- title: Servers API
|
|
10
|
+
url: https://postmarkapp.com/developer/api/servers-api
|
|
11
|
+
- title: API overview (authentication)
|
|
12
|
+
url: https://postmarkapp.com/developer/api/overview
|
|
13
|
+
api:
|
|
14
|
+
base_url: https://api.postmarkapp.com
|
|
15
|
+
base_url_env: POSTMARK_API_URL
|
|
16
|
+
auth: { header: X-Postmark-Account-Token, value_env: POSTMARK_ACCOUNT_TOKEN }
|
|
17
|
+
detect:
|
|
18
|
+
deps: [postmark]
|
|
19
|
+
env: ["POSTMARK_*"]
|
|
20
|
+
starter:
|
|
21
|
+
- op: server
|
|
22
|
+
values: { name: "sponson-${ctx.env}-${ctx.scope}" }
|
|
23
|
+
assumptions:
|
|
24
|
+
- id: PM1
|
|
25
|
+
verified: true
|
|
26
|
+
text: "The Servers API authenticates with the account token in `X-Postmark-Account-Token` (account owner only) and takes and answers JSON."
|
|
27
|
+
source: https://postmarkapp.com/developer/api/servers-api
|
|
28
|
+
- id: PM2
|
|
29
|
+
verified: true
|
|
30
|
+
text: "`POST /servers` creates a server from `Name` (required), `Color`, `DeliveryType` (`Live` or `Sandbox`, fixed after creation), `InboundHookUrl`, `TrackOpens`, `TrackLinks` and more, answering the server with its integer `ID`, its settings and `ApiTokens` (the server's tokens)."
|
|
31
|
+
source: https://postmarkapp.com/developer/api/servers-api
|
|
32
|
+
- id: PM3
|
|
33
|
+
verified: true
|
|
34
|
+
text: "`GET /servers?count=&offset=&name=` answers `{ TotalCount, Servers: [...] }`; `name` is a substring search (`MyServer` also matches `MyServer Production`), so the recipe matches the exact `Name` among the results."
|
|
35
|
+
source: https://postmarkapp.com/developer/api/servers-api
|
|
36
|
+
- id: PM4
|
|
37
|
+
verified: true
|
|
38
|
+
text: "`PUT /servers/{serverid}` changes the settings sent (everything but `DeliveryType`); `GET /servers/{serverid}` answers the server with its `ApiTokens`, so the server token stays readable."
|
|
39
|
+
source: https://postmarkapp.com/developer/api/servers-api
|
|
40
|
+
- id: PM5
|
|
41
|
+
verified: true
|
|
42
|
+
text: "`DELETE /servers/{serverid}` removes a server, but is not enabled for every account: where Postmark support has not enabled it, destroy fails and the line needs `destroy: keep`."
|
|
43
|
+
source: https://postmarkapp.com/developer/api/servers-api
|
|
44
|
+
- id: PM6
|
|
45
|
+
verified: false
|
|
46
|
+
text: "Server names are unique in the account (a second create with the same name is refused), and an account has fewer than 500 servers, so the first page of `count=500` holds the one `find` looks for."
|
|
47
|
+
- id: PM7
|
|
48
|
+
verified: false
|
|
49
|
+
text: "`Color`, `TrackOpens`, `TrackLinks` and `InboundHookUrl` are answered as sent (`InboundHookUrl` empty when unset), so they compare without drift."
|
|
50
|
+
ops:
|
|
51
|
+
server:
|
|
52
|
+
kind: resource
|
|
53
|
+
title: Server
|
|
54
|
+
summary: "A Postmark server per environment, such as `sponson-preview-pr-42`, with its inbound webhook URL and tracking settings. Its token is a sensitive output for the app's environment (`{ from: <line>.server_token }`). Located by its name; a console edit of its color, tracking or inbound hook URL is drift. Its webhooks: `postmark_server.webhook` with `credential: { from: <this line>.server_token }`."
|
|
55
|
+
covers: [postmark-server-webhook]
|
|
56
|
+
params:
|
|
57
|
+
name:
|
|
58
|
+
type: string
|
|
59
|
+
required: true
|
|
60
|
+
description: The server's name, unique in the account (PM6); its identity.
|
|
61
|
+
example: "sponson-${ctx.env}-${ctx.scope}"
|
|
62
|
+
color:
|
|
63
|
+
type: string
|
|
64
|
+
default: Blue
|
|
65
|
+
enum: [Purple, Blue, Turquoise, Green, Red, Yellow, Grey, Orange]
|
|
66
|
+
description: The server's color in the Postmark dashboard.
|
|
67
|
+
delivery_type:
|
|
68
|
+
type: string
|
|
69
|
+
default: Sandbox
|
|
70
|
+
enum: [Live, Sandbox]
|
|
71
|
+
description: "`Sandbox` accepts mail without delivering it; fixed once the server exists (sent on create only)."
|
|
72
|
+
inbound_hook_url:
|
|
73
|
+
type: string
|
|
74
|
+
default: ""
|
|
75
|
+
description: The URL inbound mail is posted to (empty for none).
|
|
76
|
+
example: "https://${ctx.scope}.preview.example.com/api/postmark/inbound"
|
|
77
|
+
track_opens:
|
|
78
|
+
type: boolean
|
|
79
|
+
default: false
|
|
80
|
+
description: Track opens of outbound mail.
|
|
81
|
+
track_links:
|
|
82
|
+
type: string
|
|
83
|
+
default: None
|
|
84
|
+
enum: [None, HtmlAndText, HtmlOnly, TextOnly]
|
|
85
|
+
description: Track link clicks of outbound mail.
|
|
86
|
+
http:
|
|
87
|
+
find:
|
|
88
|
+
path: "/servers?count=500&offset=0&name={name}"
|
|
89
|
+
list_path: /Servers
|
|
90
|
+
match: { Name: { param: name } }
|
|
91
|
+
create:
|
|
92
|
+
path: /servers
|
|
93
|
+
body: { DeliveryType: { param: delivery_type } }
|
|
94
|
+
update: { method: PUT, path: "/servers/{id}" }
|
|
95
|
+
delete: { path: "/servers/{id}" }
|
|
96
|
+
id_path: /ID
|
|
97
|
+
fields:
|
|
98
|
+
Color: { param: color }
|
|
99
|
+
InboundHookUrl: { param: inbound_hook_url }
|
|
100
|
+
TrackOpens: { param: track_opens }
|
|
101
|
+
TrackLinks: { param: track_links }
|
|
102
|
+
outputs:
|
|
103
|
+
server_token: { path: /ApiTokens/0, sensitive: true }
|
|
104
|
+
sim:
|
|
105
|
+
numeric_ids: true
|