diff --git a/mintlify-codegen/lib/openapi.ts b/mintlify-codegen/lib/openapi.ts index 174ff3ff6..e539cabdb 100644 --- a/mintlify-codegen/lib/openapi.ts +++ b/mintlify-codegen/lib/openapi.ts @@ -3,6 +3,7 @@ import type { Blueprint } from '@seamapi/blueprint' import * as types from '@seamapi/types/connect' import type Metalsmith from 'metalsmith' +import { ObjectPageMetadataSchema } from './object-page-metadata.js' import { type PathMetadata, transformSpec, @@ -27,6 +28,7 @@ export const openapi: Metalsmith.Plugin = (files, metalsmith) => { const metadata = metalsmith.metadata() as { blueprint: Blueprint pathMetadata: PathMetadata + objectPages: unknown mintlify?: MintlifyMetadata } @@ -36,6 +38,7 @@ export const openapi: Metalsmith.Plugin = (files, metalsmith) => { rawSpec, metadata.blueprint, metadata.pathMetadata, + ObjectPageMetadataSchema.parse(metadata.objectPages), ) const orderedSpec = { diff --git a/mintlify-codegen/lib/transform-spec.ts b/mintlify-codegen/lib/transform-spec.ts index 72d747167..9ee11f723 100644 --- a/mintlify-codegen/lib/transform-spec.ts +++ b/mintlify-codegen/lib/transform-spec.ts @@ -1,6 +1,7 @@ import type { Blueprint, Endpoint, SdkName } from '@seamapi/blueprint' import { supportedSdkOrder } from '../../codegen/lib/code-sample-tab-order.js' +import type { ObjectPageMetadata } from './object-page-metadata.js' export interface PathMetadataEntry { title: string @@ -137,13 +138,79 @@ function buildEndpointMap(blueprint: Blueprint): Map { return map } +/** A resource's object page: its href and the resource type it renders as + * (the noun in the page's "The Object" heading). */ +interface ObjectPageLink { + href: string + resourceType: string +} + +/** + * Map each blueprint resource type to its object page, so endpoint responses + * that reference a shared component schema can link to the resource's object + * page. Endpoint-listing and namespace pages are not object pages, and only + * resources with samples render on a default object page (mirroring + * reference.ts). Filtered views of a shared resource (e.g. /locks over + * device) don't claim the type because resources documented at their own + * route map first. + */ +function buildObjectPageLinks( + blueprint: Blueprint, + objectPages: ObjectPageMetadata, +): Map { + const links = new Map() + const add = (resourceType: string, routePath: string): void => { + if (links.has(resourceType)) return + links.set(resourceType, { + href: `/api${routePath}/object`, + resourceType, + }) + } + + for (const resource of blueprint.resources) { + const meta = objectPages[resource.routePath] + if (meta == null || meta.endpoints || meta.namespace) continue + if (meta.resource_type == null && resource.resourceSamples.length === 0) { + continue + } + if ( + meta.resource_type != null && + meta.resource_type !== resource.resourceType + ) { + continue + } + add(resource.resourceType, resource.routePath) + } + + // Pages backed by an explicit resource_type with no blueprint resource at + // their own route (e.g. /action_attempts). + for (const [routePath, meta] of Object.entries(objectPages)) { + if (meta.endpoints || meta.namespace || meta.resource_type == null) continue + add(meta.resource_type, routePath) + } + + return links +} + +/** The "See the [device object](/api/devices/object)." sentence appended to + * schema descriptions. Plain link text — a code span inside a link renders + * badly in Mintlify response fields. */ +function objectPageSentence(link: ObjectPageLink): string { + return `See the [${link.resourceType} object](${link.href}).` +} + /** * Create a scoped action_attempt inline schema for an endpoint. */ -function createScopedActionAttempt(actionType: string): object { +function createScopedActionAttempt( + actionType: string, + objectPageLink?: ObjectPageLink, +): object { return { type: 'object', - description: `Tracks the progress of this operation. Poll using the action_attempt_id.`, + description: + `Tracks the progress of this operation. Poll using the action_attempt_id.` + + (objectPageLink ? ` ${objectPageSentence(objectPageLink)}` : ''), properties: { action_attempt_id: { type: 'string', @@ -405,8 +472,10 @@ export function transformSpec( spec: any, blueprint: Blueprint, _pathMetadata: PathMetadata, + objectPages: ObjectPageMetadata = {}, ): { spec: any; stats: TransformStats } { const endpointMap = buildEndpointMap(blueprint) + const objectPageLinks = buildObjectPageLinks(blueprint, objectPages) const stats: TransformStats = { totalEndpoints: 0, withCodeSamples: 0, @@ -496,8 +565,10 @@ export function transformSpec( (actionAttemptProp.$ref || (actionAttemptProp.oneOf && actionAttemptProp.oneOf.length > 3)) ) { - responseSchema.properties.action_attempt = - createScopedActionAttempt(actionType) + responseSchema.properties.action_attempt = createScopedActionAttempt( + actionType, + objectPageLinks.get('action_attempt'), + ) stats.withActionAttempts++ } } @@ -544,7 +615,7 @@ export function transformSpec( } // Transform component schemas - transformComponents(spec) + transformComponents(spec, objectPageLinks) // Strip internal-only ("x-undocumented") properties and parameters that the // operation-level path filter above does not reach (e.g. the internal `sync` @@ -563,7 +634,10 @@ export function transformSpec( /** * Clean up component schemas for Mintlify rendering. */ -function transformComponents(spec: any): void { +function transformComponents( + spec: any, + objectPageLinks: Map, +): void { const schemas = spec.components?.schemas if (!schemas) return @@ -628,6 +702,19 @@ function transformComponents(spec: any): void { } schema.required = ['action_attempt_id', 'action_type', 'status'] } + + // Link every schema that backs an object page to that page, so endpoint + // responses that reference the schema point readers at the full resource + // reference. Appended after truncation so the link is never cut off. + const link = objectPageLinks.get(name) + if (link != null) { + const sentence = objectPageSentence(link) + // Same paragraph as the description — a separate paragraph reads as a + // detached fragment in the rendered response field. + schema.description = schema.description + ? `${schema.description} ${sentence}` + : sentence + } } } diff --git a/mintlify-docs/openapi.json b/mintlify-docs/openapi.json index 98ac10ec4..106d82fd6 100644 --- a/mintlify-docs/openapi.json +++ b/mintlify-docs/openapi.json @@ -12,7 +12,7 @@ "components": { "schemas": { "access_code": { - "description": "Represents a smart lock [access code](/low-level-apis/smart-locks/access-codes).", + "description": "Represents a smart lock [access code](/low-level-apis/smart-locks/access-codes). See the [access_code object](/api/access_codes/object).", "properties": { "access_code_id": { "description": "Unique identifier for the access code.", @@ -519,7 +519,7 @@ "x-route-path": "/access_codes" }, "access_grant": { - "description": "Represents an Access Grant. Access Grants enable you to grant a user identity access to spaces, entrances, and devices through one or more access methods, such as mobile keys, plastic cards, and PIN codes. You can create an Access Grant for an existing user identity, or you can create a new user identity *while* creating the new Access Grant.", + "description": "Represents an Access Grant. Access Grants enable you to grant a user identity access to spaces, entrances, and devices through one or more access methods, such as mobile keys, plastic cards, and PIN codes. You can create an Access Grant for an existing user identity, or you can create a new user identity *while* creating the new Access Grant. See the [access_grant object](/api/access_grants/object).", "properties": { "access_grant_id": { "description": "ID of the Access Grant.", @@ -914,7 +914,7 @@ "x-route-path": "/access_grants" }, "access_method": { - "description": "Represents an access method for an Access Grant. Access methods describe the modes of access, such as PIN codes, plastic cards, and mobile keys. For a mobile key, the access method also stores the URL for the associated Instant Key.", + "description": "Represents an access method for an Access Grant. Access methods describe the modes of access, such as PIN codes, plastic cards, and mobile keys. For a mobile key, the access method also stores the URL for the associated Instant Key. See the [access_method object](/api/access_methods/object).", "properties": { "access_method_id": { "description": "ID of the access method.", @@ -1314,7 +1314,7 @@ "x-route-path": "/access_methods" }, "acs_access_group": { - "description": "Group that defines the entrances to which a set of users has access and, in some cases, the access schedule for these entrances and users.", + "description": "Group that defines the entrances to which a set of users has access and, in some cases, the access schedule for these entrances and users. See the [acs_access_group object](/api/acs/access_groups/object).", "properties": { "access_group_type": { "deprecated": true, @@ -1916,7 +1916,7 @@ "x-route-path": "/acs/access_groups" }, "acs_credential": { - "description": "Means by which an [access control system user](/low-level-apis/access-systems/user-management) gains access at an [entrance](/low-level-apis/access-systems/retrieving-entrance-details). The `acs_credential` object represents a [credential](/low-level-apis/access-systems/managing-credentials) that provides an ACS user access within an [access control system](/low-level-apis/access-systems).", + "description": "Means by which an [access control system user](/low-level-apis/access-systems/user-management) gains access at an [entrance](/low-level-apis/access-systems/retrieving-entrance-details). The `acs_credential` object represents a [credential](/low-level-apis/access-systems/managing-credentials) that provides an ACS user access within an [access control system](/low-level-apis/access-systems). See the [acs_credential object](/api/acs/credentials/object).", "properties": { "access_method": { "description": "Access method for the [credential](/low-level-apis/access-systems/managing-credentials). Supported values: `code`, `card`, `mobile_key`, `cloud_key`.", @@ -2287,7 +2287,7 @@ "x-route-path": "/acs/credential_provisioning_automations" }, "acs_encoder": { - "description": "Represents a hardware device that encodes [credential](/low-level-apis/access-systems/managing-credentials) data onto physical cards within an [access control system](/low-level-apis/access-systems).", + "description": "Represents a hardware device that encodes [credential](/low-level-apis/access-systems/managing-credentials) data onto physical cards within an [access control system](/low-level-apis/access-systems). See the [acs_encoder object](/api/acs/encoders/object).", "properties": { "acs_encoder_id": { "description": "ID of the [encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners).", @@ -2364,7 +2364,7 @@ "x-route-path": "/acs/encoders" }, "acs_entrance": { - "description": "Represents an [entrance](/low-level-apis/access-systems/retrieving-entrance-details) within an [access control system](/low-level-apis/access-systems).", + "description": "Represents an [entrance](/low-level-apis/access-systems/retrieving-entrance-details) within an [access control system](/low-level-apis/access-systems). See the [acs_entrance object](/api/acs/entrances/object).", "properties": { "acs_entrance_id": { "description": "ID of the [entrance](/low-level-apis/access-systems/retrieving-entrance-details).", @@ -2882,7 +2882,7 @@ "x-route-path": "/acs/entrances" }, "acs_system": { - "description": "Represents an [access control system](/low-level-apis/access-systems).\n\nWithin an `acs_system`, create [`acs_user`s](/api/acs/users/object) and [`acs_credential`s](/api/acs/credentials/object) to grant access to the `acs_user`s.\n\nFor details about the resources associated with an access control system, see the [access control systems namespace](/api/acs/object).", + "description": "Represents an [access control system](/low-level-apis/access-systems).\n\nWithin an `acs_system`, create [`acs_user`s](/api/acs/users/object) and [`acs_credential`s](/api/acs/credentials/object) to grant access to the `acs_user`s.\n\nFor details about the resources associated with an access control system, see the [access control systems namespace](/api/acs/object). See the [acs_system object](/api/acs/systems/object).", "properties": { "acs_access_group_count": { "description": "Number of access groups in the [access control system](/low-level-apis/access-systems).", @@ -3180,7 +3180,7 @@ "x-route-path": "/acs/systems" }, "acs_user": { - "description": "Represents a [user](/low-level-apis/access-systems/user-management) in an [access system](/low-level-apis/access-systems).", + "description": "Represents a [user](/low-level-apis/access-systems/user-management) in an [access system](/low-level-apis/access-systems). See the [acs_user object](/api/acs/users/object).", "properties": { "access_schedule": { "description": "`starts_at` and `ends_at` timestamps for the [access system user's](/low-level-apis/access-systems/user-management) access.", @@ -3930,7 +3930,7 @@ "x-route-path": "/acs/users" }, "action_attempt": { - "description": "Represents an asynchronous action. Poll until status is success or error.", + "description": "Represents an asynchronous action. Poll until status is success or error. See the [action_attempt object](/api/action_attempts/object).", "x-route-path": "/action_attempts", "type": "object", "properties": { @@ -4391,7 +4391,7 @@ "x-route-path": "/seam/bridge/v1/bridge_connected_systems" }, "client_session": { - "description": "Represents a [client session](/core-concepts/authentication/client-session-tokens). If you want to restrict your users' access to their own devices, use client sessions.", + "description": "Represents a [client session](/core-concepts/authentication/client-session-tokens). If you want to restrict your users' access to their own devices, use client sessions. See the [client_session object](/api/client_sessions/object).", "properties": { "client_session_id": { "description": "ID of the client session.", @@ -4479,7 +4479,7 @@ "x-route-path": "/client_sessions" }, "connect_webview": { - "description": "Represents a [Connect Webview](/core-concepts/connect-webviews).", + "description": "Represents a [Connect Webview](/core-concepts/connect-webviews). See the [connect_webview object](/api/connect_webviews/object).", "properties": { "accepted_capabilities": { "description": "High-level device capabilities that the Connect Webview can accept. When creating a Connect Webview, you can specify the types of devices that it can connect to Seam. If you do not set custom `accepted_capabilities`, Seam uses a default set of `accepted_capabilities` for each provider. For example, if you create a Connect Webview that accepts SmartThing devices, without specifying `accepted_capabilities`, Seam accepts only SmartThings locks. To connect SmartThings thermostats and locks to Seam, create a Connect Webview and include both `thermostat` and `lock` in the `accepted_capabilities`.", @@ -4629,7 +4629,7 @@ "x-route-path": "/connect_webviews" }, "connected_account": { - "description": "Represents a [connected account](/core-concepts/connected-accounts). A connected account is an external third-party account to which your user has authorized Seam to get access, for example, an August account with a list of door locks.", + "description": "Represents a [connected account](/core-concepts/connected-accounts). A connected account is an external third-party account to which your user has authorized Seam to get access, for example, an August account with a list of door locks. See the [connected_account object](/api/connected_accounts/object).", "properties": { "accepted_capabilities": { "description": "List of capabilities that were accepted during the account connection process.", @@ -5005,7 +5005,7 @@ "x-route-path": "/customers" }, "customer_portal": { - "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.", + "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. See the [customer_portal object](/api/customers/object).", "properties": { "created_at": { "description": "Date and time at which the customer portal link was created.", @@ -5115,7 +5115,7 @@ "x-title": "Customization Profile" }, "device": { - "description": "Represents a [device](/core-concepts/devices) that has been connected to Seam.", + "description": "Represents a [device](/core-concepts/devices) that has been connected to Seam. See the [device object](/api/devices/object).", "properties": { "can_configure_auto_lock": { "description": "Indicates whether the lock supports configuring automatic locking.", @@ -8494,7 +8494,8 @@ "provider_categories" ], "type": "object", - "x-route-path": "/devices" + "x-route-path": "/devices", + "description": "See the [device_provider object](/api/devices/object)." }, "enrollment_automation": { "description": "Represents an [enrollment automation](/capability-guides/mobile-access/issuing-mobile-credentials-from-an-access-control-system) within the [Seam mobile access solution](/capability-guides/mobile-access).", @@ -8536,7 +8537,7 @@ "x-route-path": "/user_identities/enrollment_automations" }, "event": { - "description": "Represents an event. Events let you know when something interesting happens in your workspace. For example, when a lock is unlocked, Seam creates a `lock.unlocked` event. When a device's battery level is low, Seam creates a `device.battery_low` event.", + "description": "Represents an event. Events let you know when something interesting happens in your workspace. For example, when a lock is unlocked, Seam creates a `lock.unlocked` event. When a device's battery level is low, Seam creates a `device.battery_low` event. See the [event object](/api/events/object).", "discriminator": { "propertyName": "event_type" }, @@ -19072,7 +19073,7 @@ "x-route-path": "/events" }, "instant_key": { - "description": "Represents a Seam Instant Key. For issuing Bluetooth mobile keys, Instant Keys are the fastest way to share access. With a single API call, you can create a mobile key and send it through text or email or embed it in your own app.", + "description": "Represents a Seam Instant Key. For issuing Bluetooth mobile keys, Instant Keys are the fastest way to share access. With a single API call, you can create a mobile key and send it through text or email or embed it in your own app. See the [instant_key object](/api/instant_keys/object).", "properties": { "client_session_id": { "description": "ID of the client session associated with the Instant Key.", @@ -19185,7 +19186,7 @@ "x-route-path": "/unstable_partner/building_blocks" }, "noise_threshold": { - "description": "Represents a [noise threshold](/capability-guides/noise-sensors/configure-noise-threshold-settings) for a [noise sensor](/capability-guides/noise-sensors). Thresholds represent the limits of noise tolerated at a property, which can be customized for each hour of the day. Each device has its own default thresholds, but you can use the Seam API to modify them.", + "description": "Represents a [noise threshold](/capability-guides/noise-sensors/configure-noise-threshold-settings) for a [noise sensor](/capability-guides/noise-sensors). Thresholds represent the limits of noise tolerated at a property, which can be customized for each hour of the day. Each device has its own default thresholds, but you can use the Seam API to modify them. See the [noise_threshold object](/api/noise_sensors/noise_thresholds/object).", "properties": { "device_id": { "description": "Unique identifier for the device that contains the noise threshold.", @@ -19258,7 +19259,7 @@ "type": "object" }, "phone": { - "description": "Represents an app user's mobile phone.", + "description": "Represents an app user's mobile phone. See the [phone object](/api/phones/object).", "properties": { "created_at": { "description": "Date and time at which the phone was created.\n ", @@ -20639,7 +20640,7 @@ "x-route-path": "/seam/mobile_sdk/v1/phone_sessions" }, "space": { - "description": "Represents a space that is a logical grouping of devices and entrances. You can assign access to an entire space, thereby making granting access more efficient.", + "description": "Represents a space that is a logical grouping of devices and entrances. You can assign access to an entire space, thereby making granting access more efficient. See the [space object](/api/spaces/object).", "properties": { "acs_entrance_count": { "description": "Number of entrances in the space.", @@ -20846,7 +20847,7 @@ "x-route-path": "/seam/customer/v1/staff_members" }, "thermostat_daily_program": { - "description": "Represents a thermostat daily program, consisting of a set of periods, each of which has a starting time and the key that identifies the climate preset to apply at the starting time.", + "description": "Represents a thermostat daily program, consisting of a set of periods, each of which has a starting time and the key that identifies the climate preset to apply at the starting time. See the [thermostat_daily_program object](/api/thermostats/daily_programs/object).", "properties": { "created_at": { "description": "Date and time at which the thermostat daily program was created.", @@ -20909,7 +20910,7 @@ "x-route-path": "/thermostats/daily_programs" }, "thermostat_schedule": { - "description": "Represents a [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) that activates a configured [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) on a [thermostat](/capability-guides/thermostats) at a specified starting time and deactivates the climate preset at a specified ending time.", + "description": "Represents a [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) that activates a configured [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) on a [thermostat](/capability-guides/thermostats) at a specified starting time and deactivates the climate preset at a specified ending time. See the [thermostat_schedule object](/api/thermostats/schedules/object).", "properties": { "climate_preset_key": { "description": "Key of the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) to use for the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules).", @@ -20998,7 +20999,7 @@ "x-route-path": "/thermostats/schedules" }, "unmanaged_access_code": { - "description": "Represents an [unmanaged smart lock access code](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes).", + "description": "Represents an [unmanaged smart lock access code](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes). See the [unmanaged_access_code object](/api/access_codes/unmanaged/object).", "properties": { "access_code_id": { "description": "Unique identifier for the access code.", @@ -22824,7 +22825,7 @@ "x-route-path": "/acs/users/unmanaged" }, "unmanaged_device": { - "description": "Represents an [unmanaged device](/core-concepts/devices/managed-and-unmanaged-devices). An unmanaged device has a limited set of visible properties and a subset of supported events. You cannot control an unmanaged device. Any [access codes](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes) on an unmanaged device are unmanaged.", + "description": "Represents an [unmanaged device](/core-concepts/devices/managed-and-unmanaged-devices). An unmanaged device has a limited set of visible properties and a subset of supported events. You cannot control an unmanaged device. Any [access codes](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes) on an unmanaged device are unmanaged. See the [unmanaged_device object](/api/devices/unmanaged/object).", "properties": { "can_configure_auto_lock": { "description": "Indicates whether the lock supports configuring automatic locking.", @@ -23331,7 +23332,7 @@ "x-route-path": "/devices/unmanaged" }, "user_identity": { - "description": "Represents a [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity) associated with an application user account.", + "description": "Represents a [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity) associated with an application user account. See the [user_identity object](/api/user_identities/object).", "properties": { "acs_user_ids": { "description": "Array of access system user IDs associated with the user identity.", @@ -23520,7 +23521,7 @@ "x-route-path": "/user_identities" }, "webhook": { - "description": "Represents a [webhook](/developer-tools/webhooks) that enables you to receive notifications of events. When you create a webhook, specify the endpoint URL at which you want to receive events and the set of event types that you want to receive.", + "description": "Represents a [webhook](/developer-tools/webhooks) that enables you to receive notifications of events. When you create a webhook, specify the endpoint URL at which you want to receive events and the set of event types that you want to receive. See the [webhook object](/api/webhooks/object).", "properties": { "event_types": { "description": "Types of events that the [webhook](/developer-tools/webhooks) should receive.", @@ -23550,7 +23551,7 @@ "x-route-path": "/webhooks" }, "workspace": { - "description": "Represents a Seam [workspace](/core-concepts/workspaces). A workspace is a top-level entity that encompasses all other resources below it, such as devices, connected accounts, and Connect Webviews. Seam provides two types of workspaces. A [sandbox workspace](/core-concepts/workspaces#sandbox-workspaces) is a special type of workspace designed for testing code.", + "description": "Represents a Seam [workspace](/core-concepts/workspaces). A workspace is a top-level entity that encompasses all other resources below it, such as devices, connected accounts, and Connect Webviews. Seam provides two types of workspaces. A [sandbox workspace](/core-concepts/workspaces#sandbox-workspaces) is a special type of workspace designed for testing code. See the [workspace object](/api/workspaces/object).", "properties": { "company_name": { "description": "Company name associated with the [workspace](/core-concepts/workspaces).", @@ -31979,7 +31980,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -32280,7 +32281,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -33150,7 +33151,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -37964,7 +37965,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -38537,7 +38538,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -38709,7 +38710,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -40207,7 +40208,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -55934,7 +55935,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -56836,7 +56837,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -56998,7 +56999,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -57149,7 +57150,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -57300,7 +57301,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -62090,7 +62091,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -62251,7 +62252,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -63043,7 +63044,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -63389,7 +63390,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -63563,7 +63564,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -64195,7 +64196,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -65382,7 +65383,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -65670,7 +65671,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -66772,7 +66773,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string", @@ -71850,7 +71851,7 @@ "properties": { "action_attempt": { "type": "object", - "description": "Tracks the progress of this operation. Poll using the action_attempt_id.", + "description": "Tracks the progress of this operation. Poll using the action_attempt_id. See the [action_attempt object](/api/action_attempts/object).", "properties": { "action_attempt_id": { "type": "string",