diff --git a/codegen/data/resource-sample-definitions/all-resources.yaml b/codegen/data/resource-sample-definitions/all-resources.yaml index 431ead80a..70ec5c57c 100644 --- a/codegen/data/resource-sample-definitions/all-resources.yaml +++ b/codegen/data/resource-sample-definitions/all-resources.yaml @@ -598,11 +598,10 @@ supports_offline_access_codes: false warnings: [] workspace_id: 5d7f2e1a-9c8b-4f3e-8d2c-1a0b9e8f7c6d -- title: Magic Link - description: A magic link resource. - resource_type: magic_link +- title: Customer Portal + description: A customer portal resource. + resource_type: customer_portal properties: - building_block_type: connect_accounts created_at: '2025-06-16T16:54:17.946594Z' customer_key: My Company expires_at: '2025-06-17T16:54:17.946594Z' diff --git a/docs/api-reference/_blueprint.json b/docs/api-reference/_blueprint.json index fd27392e1..3df09e3da 100644 --- a/docs/api-reference/_blueprint.json +++ b/docs/api-reference/_blueprint.json @@ -27848,8 +27848,8 @@ "draftMessage": "", "response": { "responseType": "resource", - "responseKey": "magic_link", - "resourceType": "magic_link", + "responseKey": "customer_portal", + "resourceType": "customer_portal", "description": "OK", "actionAttemptType": null, "batchResourceTypes": null @@ -103334,6 +103334,106 @@ "propertyGroups": [], "resourceSamples": [] }, + { + "resourceType": "customer_portal", + "properties": [ + { + "name": "created_at", + "description": "Date and time at which the customer portal link was created.", + "isDeprecated": false, + "deprecationMessage": "", + "isUndocumented": false, + "undocumentedMessage": "", + "isDraft": false, + "draftMessage": "", + "propertyGroupKey": null, + "format": "datetime", + "jsonType": "string" + }, + { + "name": "customer_key", + "description": "Customer key for the customer portal.", + "isDeprecated": false, + "deprecationMessage": "", + "isUndocumented": false, + "undocumentedMessage": "", + "isDraft": false, + "draftMessage": "", + "propertyGroupKey": null, + "format": "string", + "jsonType": "string" + }, + { + "name": "expires_at", + "description": "Date and time at which the customer portal link expires.", + "isDeprecated": false, + "deprecationMessage": "", + "isUndocumented": false, + "undocumentedMessage": "", + "isDraft": false, + "draftMessage": "", + "propertyGroupKey": null, + "format": "datetime", + "jsonType": "string" + }, + { + "name": "url", + "description": "URL for the customer portal.", + "isDeprecated": false, + "deprecationMessage": "", + "isUndocumented": false, + "undocumentedMessage": "", + "isDraft": false, + "draftMessage": "", + "propertyGroupKey": null, + "format": "string", + "jsonType": "string" + }, + { + "name": "workspace_id", + "description": "ID of the [workspace](https://docs.seam.co/latest/core-concepts/workspaces) associated with the customer portal.", + "isDeprecated": false, + "deprecationMessage": "", + "isUndocumented": false, + "undocumentedMessage": "", + "isDraft": false, + "draftMessage": "", + "propertyGroupKey": null, + "format": "id", + "jsonType": "string" + } + ], + "description": "Represents a Customer Portal. Customer Portal is a hosted, customizable interface for managing device access. It enables you to embed secure, pre-authenticated access flows into your product—either by sharing a link with users or embedding a view in an iframe.\n\nWith Customer Portal, you no longer need to build out frontend experiences for physical access, thermostats, and sensors. Instead, you can ship enterprise-grade access control experiences in a fraction of the time, while maintaining your product's branding and user experience.\n\nSeam hosts these flows, handling everything from account connection and device mapping to full-featured device control.", + "isDeprecated": false, + "routePath": "/customers", + "deprecationMessage": "", + "isUndocumented": false, + "undocumentedMessage": "", + "isDraft": false, + "draftMessage": "", + "propertyGroups": [], + "resourceSamples": [ + { + "title": "Customer Portal", + "description": "A customer portal resource.", + "resource_type": "customer_portal", + "properties": { + "created_at": "2025-06-16T16:54:17.946594Z", + "customer_key": "My Company", + "expires_at": "2025-06-17T16:54:17.946594Z", + "url": "https://se.am/1234", + "workspace_id": "67c58f1f-f148-4415-a63c-dc6c145c6b91" + }, + "resource": { + "seam_cli": { + "title": "Seam CLI", + "resource_data": "{\n \"created_at\": \"2025-06-16T16:54:17.946594Z\",\n \"customer_key\": \"My Company\",\n \"expires_at\": \"2025-06-17T16:54:17.946594Z\",\n \"url\": \"https://se.am/1234\",\n \"workspace_id\": \"67c58f1f-f148-4415-a63c-dc6c145c6b91\"\n}", + "resource_data_syntax": "json" + } + } + } + ] + }, { "resourceType": "customization_profile", "properties": [ @@ -116376,28 +116476,7 @@ "isDraft": false, "draftMessage": "", "propertyGroups": [], - "resourceSamples": [ - { - "title": "Magic Link", - "description": "A magic link resource.", - "resource_type": "magic_link", - "properties": { - "building_block_type": "connect_accounts", - "created_at": "2025-06-16T16:54:17.946594Z", - "customer_key": "My Company", - "expires_at": "2025-06-17T16:54:17.946594Z", - "url": "https://se.am/1234", - "workspace_id": "67c58f1f-f148-4415-a63c-dc6c145c6b91" - }, - "resource": { - "seam_cli": { - "title": "Seam CLI", - "resource_data": "{\n \"building_block_type\": \"connect_accounts\",\n \"created_at\": \"2025-06-16T16:54:17.946594Z\",\n \"customer_key\": \"My Company\",\n \"expires_at\": \"2025-06-17T16:54:17.946594Z\",\n \"url\": \"https://se.am/1234\",\n \"workspace_id\": \"67c58f1f-f148-4415-a63c-dc6c145c6b91\"\n}", - "resource_data_syntax": "json" - } - } - } - ] + "resourceSamples": [] }, { "resourceType": "noise_threshold", diff --git a/docs/api-reference/_report.md b/docs/api-reference/_report.md index eb7d34a6c..4517f1b56 100644 --- a/docs/api-reference/_report.md +++ b/docs/api-reference/_report.md @@ -670,6 +670,8 @@ These items are deprecated. - `action_attempt` - `/access_codes/pull_backup_access_code` - `backup_access_code` +- `/customers/create_portal` + - `magic_link` - `/events/get` - `message` - `/locks/get` diff --git a/docs/api-reference/customers/README.md b/docs/api-reference/customers/README.md index 3019cf867..a71d9769c 100644 --- a/docs/api-reference/customers/README.md +++ b/docs/api-reference/customers/README.md @@ -3,6 +3,83 @@ **Early Access Preview.** The customers API is currently in Alpha. We're actively developing it and seeking early feedback at [support@seam.co](mailto:support@seam.co). Expect breaking changes as we refine the design. {% endhint %} +## The customer_portal Object + +- [Properties](./#properties) +- [Endpoints](./#endpoints) + + +Represents a Customer Portal. Customer Portal is a hosted, customizable interface for managing device access. It enables you to embed secure, pre-authenticated access flows into your product—either by sharing a link with users or embedding a view in an iframe. + +With Customer Portal, you no longer need to build out frontend experiences for physical access, thermostats, and sensors. Instead, you can ship enterprise-grade access control experiences in a fraction of the time, while maintaining your product's branding and user experience. + +Seam hosts these flows, handling everything from account connection and device mapping to full-featured device control. + +{% tabs %} +{% tab title="Customer Portal" %} + +A customer portal resource. + +```json +{ + "created_at": "2025-06-16T16:54:17.946594Z", + "customer_key": "My Company", + "expires_at": "2025-06-17T16:54:17.946594Z", + "url": "https://se.am/1234", + "workspace_id": "67c58f1f-f148-4415-a63c-dc6c145c6b91" +} +``` +{% endtab %} +{% endtabs %} + +--- +## Properties + +**`created_at`** *Datetime* + +Date and time at which the customer portal link was created. + + + + +--- + +**`customer_key`** *String* + +Customer key for the customer portal. + + + + +--- + +**`expires_at`** *Datetime* + +Date and time at which the customer portal link expires. + + + + +--- + +**`url`** *String* + +URL for the customer portal. + + + + +--- + +**`workspace_id`** *UUID* + +ID of the [workspace](https://docs.seam.co/latest/core-concepts/workspaces) associated with the customer portal. + + + + +--- + ## Endpoints diff --git a/docs/api-reference/customers/create_portal.md b/docs/api-reference/customers/create_portal.md index 2cc1eb806..cf74c5008 100644 --- a/docs/api-reference/customers/create_portal.md +++ b/docs/api-reference/customers/create_portal.md @@ -418,7 +418,7 @@ Navigation mode for the portal. 'restricted' tells frontend to hide navigation U {% hint style="success" %} Returns: -**[magic\_link](./../unstable_partner/building_blocks)** +**[customer\_portal](.)** {% endhint %} @@ -430,7 +430,6 @@ Returns: ```json { - "building_block_type": "connect_accounts", "created_at": "2025-06-16T16:54:17.946594Z", "customer_key": "My Company", "expires_at": "2025-06-17T16:54:17.946594Z", diff --git a/docs/guides/capability-guides/customer-portals/filtering-portal-resources-by-custom-metadata.md b/docs/guides/capability-guides/customer-portals/filtering-portal-resources-by-custom-metadata.md index c526f0ecb..cff33e2db 100644 --- a/docs/guides/capability-guides/customer-portals/filtering-portal-resources-by-custom-metadata.md +++ b/docs/guides/capability-guides/customer-portals/filtering-portal-resources-by-custom-metadata.md @@ -49,7 +49,7 @@ Create property listings with a `region` field in `custom_metadata`, then filter {% tabs %} {% tab title="JavaScript" %} ```javascript -const { magic_link } = await seam.customers.createPortal({ +const { customer_portal } = await seam.customers.createPortal({ customer_data: { customer_key: "customer_123", property_listings: [ @@ -71,7 +71,7 @@ const { magic_link } = await seam.customers.createPortal({ }); // The portal will only show "Lisbon Apartment" -console.log(magic_link.url); +console.log(customer_portal.url); ``` {% endtab %} @@ -112,7 +112,7 @@ When you provide multiple filters, a resource must match all of them. Here, only {% tabs %} {% tab title="JavaScript" %} ```javascript -const { magic_link } = await seam.customers.createPortal({ +const { customer_portal } = await seam.customers.createPortal({ customer_data: { customer_key: "customer_123", property_listings: [ @@ -140,7 +140,7 @@ const { magic_link } = await seam.customers.createPortal({ }); // Only "Premium Villa" is visible in the portal -console.log(magic_link.url); +console.log(customer_portal.url); ``` {% endtab %} @@ -187,7 +187,7 @@ Filter by a boolean `custom_metadata` value, such as showing only premium listin {% tabs %} {% tab title="JavaScript" %} ```javascript -const { magic_link } = await seam.customers.createPortal({ +const { customer_portal } = await seam.customers.createPortal({ customer_data: { customer_key: "customer_123", property_listings: [ @@ -209,7 +209,7 @@ const { magic_link } = await seam.customers.createPortal({ }); // Only "Premium Villa" is visible -console.log(magic_link.url); +console.log(customer_portal.url); ``` {% endtab %} @@ -250,7 +250,7 @@ Filters also apply to reservations. Here, only reservations that are both premiu {% tabs %} {% tab title="JavaScript" %} ```javascript -const { magic_link } = await seam.customers.createPortal({ +const { customer_portal } = await seam.customers.createPortal({ customer_data: { customer_key: "customer_123", property_listings: [ @@ -287,7 +287,7 @@ const { magic_link } = await seam.customers.createPortal({ }); // Only "Premium EU Reservation" is visible in the portal -console.log(magic_link.url); +console.log(customer_portal.url); ``` {% endtab %} diff --git a/docs/guides/capability-guides/customer-portals/integrate-customer-portal-into-your-application.md b/docs/guides/capability-guides/customer-portals/integrate-customer-portal-into-your-application.md index 00454bfbd..1dcc1db32 100644 --- a/docs/guides/capability-guides/customer-portals/integrate-customer-portal-into-your-application.md +++ b/docs/guides/capability-guides/customer-portals/integrate-customer-portal-into-your-application.md @@ -56,7 +56,7 @@ The Seam Customer Portal is a hosted, pre-authenticated interface for managing d ### How it works -When you create a customer portal via the API, Seam returns a `magic_link` URL. This URL can be loaded in a standard HTML ` ``` -In practice, your backend generates the `magic_link.url` and passes it to your frontend, which sets it as the iFrame `src`. Don't hardcode the URL — it contains a session token that expires. +In practice, your backend generates the `customer_portal.url` and passes it to your frontend, which sets it as the iFrame `src`. Don't hardcode the URL — it contains a session token that expires. ### Step 3: Refresh the link before it expires diff --git a/package-lock.json b/package-lock.json index 35c3bd2e5..55828ce74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,9 +12,9 @@ "@metalsmith/metadata": "^0.3.0", "@prettier/plugin-php": "^0.24.0", "@prettier/plugin-ruby": "^4.0.4", - "@seamapi/blueprint": "^0.53.2", + "@seamapi/blueprint": "^0.55.0", "@seamapi/smith": "^0.5.2", - "@seamapi/types": "1.803.0", + "@seamapi/types": "1.805.0", "@types/command-exists": "^1.2.3", "change-case": "^5.4.4", "command-exists": "^1.2.9", @@ -935,9 +935,9 @@ "license": "MIT" }, "node_modules/@seamapi/blueprint": { - "version": "0.53.2", - "resolved": "https://registry.npmjs.org/@seamapi/blueprint/-/blueprint-0.53.2.tgz", - "integrity": "sha512-L991izMQpQGpwknIdPB1Y9tk70fXTycmLMspgELAQlR0N536WlQgj/cXpt8TIX37g/UNfHaPOrIWZindn66s+Q==", + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@seamapi/blueprint/-/blueprint-0.55.0.tgz", + "integrity": "sha512-2Xk3XQ486WufuZ4ar7aP1XWQXaadg04x1VVjHGWrI1lMpSfWAeOTs8ol3EdRzI/NK6pUdIfgED86aH62KsyQ9w==", "dev": true, "license": "MIT", "dependencies": { @@ -983,9 +983,9 @@ } }, "node_modules/@seamapi/types": { - "version": "1.803.0", - "resolved": "https://registry.npmjs.org/@seamapi/types/-/types-1.803.0.tgz", - "integrity": "sha512-dy35ew29Znc3bBz9vgosOa/Fb2mGAEapGEU9Ff5xl+HsWeRuwZzVNoZ3ffH8jJ9dIPOqmPM/BCDzrzEdH9cMuw==", + "version": "1.805.0", + "resolved": "https://registry.npmjs.org/@seamapi/types/-/types-1.805.0.tgz", + "integrity": "sha512-G9STdKRht2qkUAp7jqQdH7U75N1UDUJspt/TnfRVaI0EO1GTWAjGd7NfVm28rsB8rkU9sN2M3fb6TBGUjfwfdA==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index ca0c7ed96..077d53fc1 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,9 @@ "@metalsmith/metadata": "^0.3.0", "@prettier/plugin-php": "^0.24.0", "@prettier/plugin-ruby": "^4.0.4", - "@seamapi/blueprint": "^0.53.2", + "@seamapi/blueprint": "^0.55.0", "@seamapi/smith": "^0.5.2", - "@seamapi/types": "1.803.0", + "@seamapi/types": "1.805.0", "@types/command-exists": "^1.2.3", "change-case": "^5.4.4", "command-exists": "^1.2.9",