diff --git a/.mock/definition/__package__.yml b/.mock/definition/__package__.yml index db84636..250c1b4 100644 --- a/.mock/definition/__package__.yml +++ b/.mock/definition/__package__.yml @@ -67,18 +67,24 @@ errors: ConflictError: status-code: 409 type: unknown - docs: Site is published to multiple domains at different times + docs: Collection already exists examples: + - value: + code: duplicate_collection + message: Collection already exists - value: message: '''Site is published to multiple domains at different times' + - value: + code: conflict + message: >- + Conflict: Conflict with server data: Live PATCH updates can't be + applied to items that have never been published - value: code: custom_code_max_registered_scripts message: The maximum number of registered scripts has been reached. - value: code: forms_require_republish message: To access this feature, the site needs to be republished. - - value: - key: value - value: code: ecommerce_not_enabled message: Ecommerce is not yet initialized @@ -87,7 +93,7 @@ types: discriminated: false union: - InvalidScopes - - UsersNotEnabled + - NotEnterprisePlanSite source: openapi: ../../../openapi/referenced-specs/v2.yml BadRequestErrorBody: @@ -97,11 +103,24 @@ types: - NoDomains source: openapi: ../../../openapi/referenced-specs/v2.yml - ConflictErrorBody: - discriminated: false - union: - - DuplicateUserEmail - - UserLimitReached + ItemsListItemsRequestLastPublished: + properties: + lte: + type: optional + docs: Filter items last published before this date + gte: + type: optional + docs: Filter items last published after this date + source: + openapi: ../../../openapi/referenced-specs/v2.yml + ItemsListItemsLiveRequestLastPublished: + properties: + lte: + type: optional + docs: Filter items last published before this date + gte: + type: optional + docs: Filter items last published after this date source: openapi: ../../../openapi/referenced-specs/v2.yml AuthorizedUser: @@ -173,7 +192,24 @@ types: docs: Array of errors source: openapi: ../../../openapi/referenced-specs/v2.yml - Application: unknown + Application: + properties: + id: + type: optional + docs: Unique identifier for the Application + description: + type: optional + docs: Application description provided by the developer + homepage: + type: optional + docs: Application homepage URL provided by the developer + validation: + format: uri + displayName: + type: optional + docs: Application name provided by the developer + source: + openapi: ../../../openapi/referenced-specs/v2.yml AuthorizationAuthorizationAuthorizedTo: properties: siteIds: @@ -232,6 +268,7 @@ types: lastPublished: type: optional docs: The date the custom domain was last published to + access: read-only source: openapi: ../../../openapi/referenced-specs/v2.yml Locale: @@ -329,6 +366,330 @@ types: openapi: ../../../openapi/referenced-specs/v2.yml InvalidScopes: unknown NotEnterprisePlanWorkspace: unknown + WorkspaceAuditLogItemPayloadUserAccessMethod: + enum: + - dashboard + - sso + - api + - google + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + User access: + properties: + method: optional + location: + type: optional + docs: The geolocation based on the logged IP address + ipAddress: + type: optional + docs: The captured IP address of the user + source: + openapi: ../../../openapi/referenced-specs/v2.yml + UserAccessAuditLogItemEventSubType: + enum: + - login + - logout + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + UserAccessAuditLogItem: + properties: + eventSubType: optional + payload: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + Custom role: + properties: + roleName: + type: optional + docs: The name of the custom role + previousRoleName: + type: optional + docs: The previous name of the custom role + source: + openapi: ../../../openapi/referenced-specs/v2.yml + CustomRoleAuditLogItemEventSubType: + enum: + - role_created + - role_updated + - role_deleted + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + CustomRoleAuditLogItem: + properties: + eventSubType: optional + payload: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + WorkspaceAuditLogItemPayloadWorkspaceMembershipTargetUser: + properties: + id: optional + email: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + WorkspaceAuditLogItemPayloadWorkspaceMembershipMethod: + enum: + - sso + - dashboard + - admin + - access_request + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + WorkspaceAuditLogItemPayloadWorkspaceMembershipUserType: + enum: + - member + - guest + - reviewer + - client + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + Workspace membership: + properties: + targetUser: optional + method: optional + userType: optional + roleName: + type: optional + docs: The name of the role that was assigned to the user + previousRoleName: + type: optional + docs: The previous role that the user had + source: + openapi: ../../../openapi/referenced-specs/v2.yml + WorkspaceMembershipAuditLogItemEventSubType: + enum: + - user_added + - user_removed + - user_role_updated + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + WorkspaceMembershipAuditLogItem: + properties: + eventSubType: optional + payload: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + WorkspaceAuditLogItemPayloadSiteMembershipSite: + properties: + id: optional + slug: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + WorkspaceAuditLogItemPayloadSiteMembershipTargetUser: + properties: + id: optional + email: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + WorkspaceAuditLogItemPayloadSiteMembershipMethod: + enum: + - sso + - invite + - scim + - dashboard + - admin + - access_request + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + WorkspaceAuditLogItemPayloadSiteMembershipUserType: + enum: + - member + - guest + - reviewer + - client + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + WorkspaceAuditLogItemPayloadSiteMembershipGranularAccess: + properties: + id: optional + name: optional + type: optional> + restricted: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + Site membership: + properties: + site: optional + targetUser: optional + method: optional + userType: optional + roleName: + type: optional + docs: The name of the role that was assigned to the user + previousRoleName: + type: optional + docs: The previous role that the user had + granularAccess: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + SiteMembershipAuditLogItemEventSubType: + enum: + - user_added + - user_removed + - user_role_updated + - user_granular_access_updated + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + SiteMembershipAuditLogItem: + properties: + eventSubType: optional + payload: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUser: + properties: + id: optional + email: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + WorkspaceAuditLogItemPayloadWorkspaceInvitationMethod: + enum: + - sso + - dashboard + - admin + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + WorkspaceAuditLogItemPayloadWorkspaceInvitationUserType: + enum: + - member + - guest + - reviewer + - client + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUsersItem: + properties: + id: optional + email: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + Workspace invitation: + properties: + targetUser: optional + method: optional + userType: optional + roleName: + type: optional + docs: The name of the role that was assigned to the user + previousRoleName: + type: optional + docs: The previous role that the user had + targetUsers: >- + optional> + source: + openapi: ../../../openapi/referenced-specs/v2.yml + WorkspaceInvitationAuditLogItemEventSubType: + enum: + - invite_sent + - invite_accepted + - invite_updated + - invite_canceled + - invite_declined + - access_request_accepted + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + WorkspaceInvitationAuditLogItem: + properties: + eventSubType: optional + payload: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + WorkspaceAuditLogItemPayloadSettingChangeMethod: + enum: + - dashboard + - admin + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + Setting change: + properties: + setting: optional> + previousValue: optional + value: optional + method: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + SettingChangeAuditLogItem: + properties: + eventSubType: optional> + payload: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + WorkspaceAuditLogItemActor: + properties: + id: optional + email: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + WorkspaceAuditLogItemWorkspace: + properties: + id: optional + slug: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + WorkspaceAuditLogItem: + discriminant: eventType + base-properties: + timestamp: optional + actor: optional + workspace: optional + union: + user_access: + type: UserAccessAuditLogItem + custom_role: + type: CustomRoleAuditLogItem + workspace_membership: + type: WorkspaceMembershipAuditLogItem + site_membership: + type: SiteMembershipAuditLogItem + workspace_invitation: + type: WorkspaceInvitationAuditLogItem + workspace_setting: + type: SettingChangeAuditLogItem + source: + openapi: ../../../openapi/referenced-specs/v2.yml + Pagination: + docs: Pagination object + properties: + limit: + type: optional + docs: The limit used for pagination + access: read-only + offset: + type: optional + docs: The offset used for pagination + access: read-only + total: + type: optional + docs: The total number of records + access: read-only + source: + openapi: ../../../openapi/referenced-specs/v2.yml + WorkspaceAuditLogResponse: + properties: + items: optional> + pagination: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml Sites: properties: sites: optional> @@ -348,6 +709,7 @@ types: id: type: optional docs: The ID of the specific redirect rule + access: read-only fromUrl: type: optional docs: The source URL path that will be redirected. @@ -356,20 +718,6 @@ types: docs: The target URL path where the user or client will be redirected. source: openapi: ../../../openapi/referenced-specs/v2.yml - Pagination: - docs: Pagination object - properties: - limit: - type: optional - docs: The limit used for pagination - offset: - type: optional - docs: The offset used for pagination - total: - type: optional - docs: The total number of records - source: - openapi: ../../../openapi/referenced-specs/v2.yml Redirects: docs: Site redirects response properties: @@ -440,6 +788,31 @@ types: docs: URL for more information about Webflow hosting plan pricing. source: openapi: ../../../openapi/referenced-specs/v2.yml + RobotsRulesItem: + properties: + userAgent: + type: string + docs: The user agent the rules apply to. + allows: + type: optional> + docs: List of paths allowed for this user agent. + disallows: + type: optional> + docs: List of paths disallowed for this user agent. + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + Robots: + docs: The robots.txt file for a given site + properties: + rules: + type: optional> + docs: List of rules for user agents. + sitemap: + type: optional + docs: URL to the sitemap. + source: + openapi: ../../../openapi/referenced-specs/v2.yml SiteActivityLogItemEvent: enum: - styles_modified @@ -549,9 +922,11 @@ types: createdOn: type: optional docs: The date the collection was created + access: read-only lastUpdated: type: optional docs: The date the collection was last updated + access: read-only source: openapi: ../../../openapi/referenced-specs/v2.yml CollectionList: @@ -561,12 +936,12 @@ types: docs: An array of Collections source: openapi: ../../../openapi/referenced-specs/v2.yml - FieldType: + StaticFieldType: enum: - Color - DateTime - Email - - ExtFileRef + - File - Image - Link - MultiImage @@ -575,31 +950,27 @@ types: - PlainText - RichText - Switch - - Video + - VideoLink docs: Choose these appropriate field type for your collection data inline: true source: openapi: ../../../openapi/referenced-specs/v2.yml - Field: - docs: The details of a field in a collection + Static Field: properties: id: - type: string + type: optional docs: Unique identifier for a Field - isRequired: - type: boolean - docs: define whether a field is required in a collection + access: read-only isEditable: type: optional docs: Define whether the field is editable + access: read-only + isRequired: + type: optional + docs: define whether a field is required in a collection type: - type: FieldType + type: StaticFieldType docs: Choose these appropriate field type for your collection data - slug: - type: optional - docs: >- - Slug of Field in Site URL structure. Slugs should be all lowercase - with no spaces. Any spaces will be converted to "-." displayName: type: string docs: The name of a field @@ -608,29 +979,216 @@ types: docs: Additional text to help anyone filling out this field source: openapi: ../../../openapi/referenced-specs/v2.yml - Collection: - docs: A collection object + MetadataOptionsItem: + docs: A single option value for the Option field. properties: - id: + name: type: string - docs: Unique identifier for a Collection - displayName: + docs: The name of the option + id: type: optional - docs: Name given to the Collection - singularName: + docs: The unique identifier of the option + access: read-only + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + Metadata: + docs: The metadata for the Option field. + properties: + options: + docs: The option values for the Option field. + type: list + source: + openapi: ../../../openapi/referenced-specs/v2.yml + Option Field: + properties: + id: type: optional - docs: >- - The name of one Item in Collection (e.g. ”Blog Post” if the Collection - is called “Blog Posts”) - slug: + docs: Unique identifier for a Field + access: read-only + isEditable: + type: optional + docs: Define whether the field is editable + access: read-only + isRequired: + type: optional + docs: define whether a field is required in a collection + type: + type: literal<"Option"> + docs: >- + The [Option field + type](/data/reference/field-types-item-values#option) + displayName: + type: string + docs: The name of a field + helpText: + type: optional + docs: Additional text to help anyone filling out this field + metadata: Metadata + source: + openapi: ../../../openapi/referenced-specs/v2.yml + ReferenceFieldType: + enum: + - MultiReference + - Reference + docs: Choose these appropriate field type for your collection data + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + ReferenceFieldMetadata: + docs: >- + The collectionId for the referenced collection. Only applicable for + Reference and MultiReference fields. + properties: + collectionId: + type: string + docs: The unique identifier of the collection + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + Reference Field: + properties: + id: + type: optional + docs: Unique identifier for a Field + access: read-only + isEditable: + type: optional + docs: Define whether the field is editable + access: read-only + isRequired: + type: optional + docs: define whether a field is required in a collection + type: + type: ReferenceFieldType + docs: Choose these appropriate field type for your collection data + displayName: + type: string + docs: The name of a field + helpText: + type: optional + docs: Additional text to help anyone filling out this field + metadata: + type: ReferenceFieldMetadata + docs: >- + The collectionId for the referenced collection. Only applicable for + Reference and MultiReference fields. + source: + openapi: ../../../openapi/referenced-specs/v2.yml + FieldCreate: + discriminated: false + docs: Details about the field of a collection + union: + - type: Static Field + - type: Option Field + - type: Reference Field + source: + openapi: ../../../openapi/referenced-specs/v2.yml + FieldType: + enum: + - Color + - DateTime + - Email + - ExtFileRef + - File + - Image + - Link + - MultiImage + - MultiReference + - Number + - Option + - Phone + - PlainText + - Reference + - RichText + - Switch + - VideoLink + docs: Choose these appropriate field type for your collection data + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + FieldValidationsAdditionalPropertiesAdditionalProperties: + properties: + additionalProperties: unknown + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + FieldValidationsAdditionalProperties: + discriminated: false + union: + - string + - double + - boolean + - integer + - FieldValidationsAdditionalPropertiesAdditionalProperties + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + FieldValidations: + docs: The validations for the field + properties: + additionalProperties: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + Field: + docs: The details of a field in a collection + properties: + id: + type: string + docs: Unique identifier for a Field + isRequired: + type: boolean + docs: define whether a field is required in a collection + isEditable: + type: optional + docs: Define whether the field is editable + access: read-only + type: + type: FieldType + docs: Choose these appropriate field type for your collection data + slug: + type: optional + docs: >- + Slug of Field in Site URL structure. Slugs should be all lowercase + with no spaces. Any spaces will be converted to "-." + displayName: + type: string + docs: The name of a field + helpText: + type: optional + docs: Additional text to help anyone filling out this field + validations: + type: optional + docs: The validations for the field + access: read-only + source: + openapi: ../../../openapi/referenced-specs/v2.yml + Collection: + docs: A collection object + properties: + id: + type: string + docs: Unique identifier for a Collection + displayName: + type: string + docs: Name given to the Collection + singularName: + type: string + docs: >- + The name of one Item in Collection (e.g. ”Blog Post” if the Collection + is called “Blog Posts”) + slug: type: optional docs: Slug of Collection in Site URL structure createdOn: type: optional docs: The date the collection was created + access: read-only lastUpdated: type: optional docs: The date the collection was last updated + access: read-only fields: docs: The list of fields in the Collection type: list @@ -669,18 +1227,22 @@ types: id: type: optional docs: Unique identifier for the Item + access: read-only cmsLocaleId: type: optional docs: Identifier for the locale of the CMS item lastPublished: type: optional docs: The date the item was last published + access: read-only lastUpdated: type: optional docs: The date the item was last updated + access: read-only createdOn: type: optional docs: The date the item was created + access: read-only isArchived: type: optional docs: Boolean determining if the Item is set to archived @@ -695,15 +1257,15 @@ types: CollectionItemListPagination: properties: limit: - type: optional + type: optional docs: The limit specified in the request default: 100 offset: - type: optional + type: optional docs: The offset specified for pagination default: 0 total: - type: optional + type: optional docs: Total number of items in the collection source: openapi: ../../../openapi/referenced-specs/v2.yml @@ -750,18 +1312,22 @@ types: id: type: optional docs: Unique identifier for the Item + access: read-only cmsLocaleId: type: optional docs: Identifier for the locale of the CMS item lastPublished: type: optional docs: The date the item was last published + access: read-only lastUpdated: type: optional docs: The date the item was last updated + access: read-only createdOn: type: optional docs: The date the item was created + access: read-only isArchived: type: optional docs: Boolean determining if the Item is in an archived state. @@ -769,7 +1335,7 @@ types: isDraft: type: optional docs: Boolean determining if the Item is in a draft state. - default: false + default: true fieldData: CollectionItemPostSingleFieldData source: openapi: ../../../openapi/referenced-specs/v2.yml @@ -803,12 +1369,15 @@ types: lastPublished: type: optional docs: The date the item was last published + access: read-only lastUpdated: type: optional docs: The date the item was last updated + access: read-only createdOn: type: optional docs: The date the item was created + access: read-only isArchived: type: optional docs: Boolean determining if the Item is set to archived @@ -826,6 +1395,7 @@ types: docs: List of Items within the collection source: openapi: ../../../openapi/referenced-specs/v2.yml + Conflict: unknown BulkCollectionItemFieldData: properties: name: @@ -848,7 +1418,7 @@ types: items properties: id: - type: string + type: optional docs: Unique identifier for the Item cmsLocaleIds: type: optional> @@ -856,12 +1426,15 @@ types: lastPublished: type: optional docs: The date the item was last published + access: read-only lastUpdated: type: optional docs: The date the item was last updated + access: read-only createdOn: type: optional docs: The date the item was created + access: read-only isArchived: type: optional docs: Boolean determining if the Item is set to archived @@ -897,18 +1470,22 @@ types: id: type: optional docs: Unique identifier for the Item + access: read-only cmsLocaleId: type: optional docs: Identifier for the locale of the CMS item lastPublished: type: optional docs: The date the item was last published + access: read-only lastUpdated: type: optional docs: The date the item was last updated + access: read-only createdOn: type: optional docs: The date the item was created + access: read-only isArchived: type: optional docs: Boolean determining if the Item is set to archived @@ -918,6 +1495,210 @@ types: fieldData: optional source: openapi: ../../../openapi/referenced-specs/v2.yml + CommentThreadAuthor: + properties: + userId: + type: string + docs: The unique identifier of the author + email: + type: string + docs: Email of the author + name: + type: string + docs: Name of the author + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + CommentThreadMentionedUsersItem: + properties: + userId: + type: string + docs: The unique identifier of the mentioned user + email: + type: string + docs: Email of the user + name: + type: string + docs: Name of the User + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + CommentThread: + docs: > + A comment thread represents a conversation between users on a specific + page. Each comment thread has a unique identifier and can contain multiple + comments. Retrieve comment replies using the replies API endpoint. + properties: + id: + type: string + docs: Unique identifier for the comment thread + siteId: + type: string + docs: The site unique identifier + pageId: + type: string + docs: The page unique identifier + localeId: + type: optional + docs: The locale unique identifier + access: read-only + itemId: + type: optional + docs: The item unique identifier + access: read-only + breakpoint: + type: string + docs: The breakpoint the comment was left on + url: + type: string + docs: The URL of the page the comment was left on + content: + type: string + docs: The content of the comment reply + isResolved: + type: boolean + docs: Boolean determining if the comment thread is resolved + default: false + author: CommentThreadAuthor + mentionedUsers: + docs: >- + List of mentioned users. This is an empty array until email + notifications are sent, which can take up to 5 minutes after the + comment is created. + type: list + createdOn: + type: string + docs: The date the item was created + lastUpdated: + type: string + docs: The date the item was last updated + source: + openapi: ../../../openapi/referenced-specs/v2.yml + CommentThreadListPagination: + properties: + limit: + type: integer + docs: The limit specified in the request (default 100) + default: 100 + offset: + type: integer + docs: The offset specified for pagination + default: 0 + total: + type: integer + docs: Total number of comment threads + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + CommentThreadList: + docs: > + A list of comment threads on the site. Contains the content of the first + reply. + properties: + comments: list + pagination: CommentThreadListPagination + source: + openapi: ../../../openapi/referenced-specs/v2.yml + CommentReplyAuthor: + properties: + id: + type: string + docs: The unique identifier of the author + email: + type: string + docs: Email of the author + name: + type: string + docs: Name of the author + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + CommentReplyMentionedUsersItem: + properties: + id: + type: string + docs: The unique identifier of the mentioned user + email: + type: string + docs: Email of the user + name: + type: string + docs: Name of the User + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + CommentReply: + docs: > + A comment thread represents a conversation between users on a specific + page. Each comment thread has a unique identifier and can contain multiple + comments. + properties: + id: + type: string + docs: Unique identifier for the comment thread + commentId: + type: string + docs: The comment reply unique identifier + siteId: + type: string + docs: The site unique identifier + pageId: + type: string + docs: The page unique identifier + localeId: + type: optional + docs: The locale unique identifier + access: read-only + breakpoint: + type: string + docs: The breakpoint the comment was left on + content: + type: string + docs: The content of the comment reply + isResolved: + type: boolean + docs: Boolean determining if the comment thread is resolved + default: false + author: CommentReplyAuthor + mentionedUsers: + type: optional> + docs: >- + List of mentioned users is an empty array until email notifications + are sent. + lastUpdated: + type: optional + docs: The date the item was last updated + access: read-only + createdOn: + type: optional + docs: The date the item was created + access: read-only + source: + openapi: ../../../openapi/referenced-specs/v2.yml + CommentReplyListPagination: + properties: + limit: + type: integer + docs: The limit specified in the request (default 100) + default: 100 + offset: + type: integer + docs: The offset specified for pagination + default: 0 + total: + type: integer + docs: Total number of comment replies + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + CommentReplyList: + docs: | + A list of comment replies. + properties: + comments: list + pagination: CommentReplyListPagination + source: + openapi: ../../../openapi/referenced-specs/v2.yml PageSeo: docs: SEO-related fields for the Page properties: @@ -940,6 +1721,7 @@ types: type: optional docs: Indicates the Open Graph title was copied from the SEO title default: true + access: read-only description: type: optional docs: The description supplied to Open Graph annotations @@ -949,6 +1731,7 @@ types: Indicates the Open Graph description was copied from the SEO description default: true + access: read-only source: openapi: ../../../openapi/referenced-specs/v2.yml inline: true @@ -961,6 +1744,7 @@ types: siteId: type: optional docs: Unique identifier for the Site + access: read-only title: type: optional docs: Title of the Page @@ -970,43 +1754,49 @@ types: parentId: type: optional docs: Identifier of the parent folder + access: read-only collectionId: type: optional docs: >- Unique identifier for a linked Collection, value will be null if the Page is not part of a Collection. + access: read-only createdOn: type: optional docs: The date the Page was created + access: read-only lastUpdated: type: optional docs: The date the Page was most recently updated + access: read-only archived: type: optional docs: Whether the Page has been archived default: false + access: read-only draft: type: optional docs: Whether the Page is a draft default: false + access: read-only canBranch: type: optional docs: >- Indicates whether the Page supports [Page - Branching](https://university.webflow.com/lesson/page-branching) + Branching](https://university.webflow.com/lesson/page-branching). + Pages that are already branches cannot be branched again. default: false + access: read-only isBranch: type: optional docs: >- Indicates whether the Page is a Branch of another Page [Page Branching](https://university.webflow.com/lesson/page-branching) default: false - isMembersOnly: - type: optional - docs: >- - Indicates whether the Page is restricted by [Memberships - Controls](https://university.webflow.com/lesson/webflow-memberships-overview#how-to-manage-page-restrictions) - default: false + access: read-only + branchId: + type: optional + docs: If the Page is a Branch of another Page, this is the ID of the Branch seo: type: optional docs: SEO-related fields for the Page @@ -1016,9 +1806,11 @@ types: localeId: type: optional docs: Unique ID of the page locale + access: read-only publishedPath: type: optional docs: Relative path of the published page URL + access: read-only source: openapi: ../../../openapi/referenced-specs/v2.yml PageList: @@ -1029,6 +1821,7 @@ types: source: openapi: ../../../openapi/referenced-specs/v2.yml TextNodeText: + docs: The text content of the node properties: html: type: optional @@ -1046,15 +1839,18 @@ types: text for styling or other purposes. properties: id: - type: optional + type: string docs: Node UUID - text: optional + text: + type: TextNodeText + docs: The text content of the node attributes: type: optional> docs: The custom attributes of the node source: openapi: ../../../openapi/referenced-specs/v2.yml ImageNodeImage: + docs: The image details of the node properties: alt: optional assetId: optional @@ -1069,15 +1865,18 @@ types: can be associated with the image for styling or other purposes. properties: id: - type: optional + type: string docs: Node UUID - image: optional + image: + type: ImageNodeImage + docs: The image details of the node attributes: type: optional> docs: The custom attributes of the node source: openapi: ../../../openapi/referenced-specs/v2.yml Text: + docs: The text content of the node properties: html: type: optional @@ -1128,14 +1927,96 @@ types: the component instance, such as its type and properties. properties: id: - type: optional - docs: Node UUID + type: string + docs: The unique identifier of the component instance node componentId: - type: optional - docs: Component ID + type: string + docs: The unique identifier of the component propertyOverrides: - type: optional> docs: List of component properties with overrides for a component instance. + type: list + source: + openapi: ../../../openapi/referenced-specs/v2.yml + TextInputNode: + docs: > + Represents text input and textarea elements within the DOM. It contains + the placeholder text in the input. Additional attributes can be associated + with the text for styling or other purposes. + properties: + id: + type: string + docs: Node UUID + placeholder: + type: string + docs: The placeholder text of the input node + attributes: + type: optional> + docs: The custom attributes of the node + source: + openapi: ../../../openapi/referenced-specs/v2.yml + SelectNodeChoicesItem: + properties: + value: + type: string + docs: The value of the choice when selected. + text: + type: string + docs: The text to display for the choice. + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + SelectNode: + docs: > + Represents select elements within the DOM. It contains the list of choices + in the select. Additional attributes can be associated with the text for + styling or other purposes. + properties: + id: + type: string + docs: Node UUID + choices: + docs: The list of choices in this select node. + type: list + attributes: + type: optional> + docs: The custom attributes of the node + source: + openapi: ../../../openapi/referenced-specs/v2.yml + SubmitButtonNode: + docs: > + Represents submit button elements within the DOM. It contains the text and + waiting text of the button. Additional attributes can be associated with + the text for styling or other purposes. + properties: + id: + type: string + docs: Node UUID + value: + type: string + docs: The text content of the submit button. + waitingText: + type: string + docs: The text to show while the form is submitting. + attributes: + type: optional> + docs: The custom attributes of the node + source: + openapi: ../../../openapi/referenced-specs/v2.yml + SearchButtonNode: + docs: > + Represents search button elements within the DOM. It contains the text of + the button. Additional attributes can be associated with the text for + styling or other purposes. + properties: + id: + type: string + docs: Node UUID + value: + type: string + docs: The text content of the search button. + attributes: + type: optional> + docs: The custom attributes of the node source: openapi: ../../../openapi/referenced-specs/v2.yml Node: @@ -1146,9 +2027,20 @@ types: Model (DOM). Each node has a unique identifier and a specific type that determines its content structure and attributes. union: - text: TextNode - image: ImageNode - component-instance: ComponentNode + text: + type: TextNode + image: + type: ImageNode + component-instance: + type: ComponentNode + text-input: + type: TextInputNode + select: + type: SelectNode + submit-button: + type: SubmitButtonNode + search-button: + type: SearchButtonNode source: openapi: ../../../openapi/referenced-specs/v2.yml Dom: @@ -1163,8 +2055,17 @@ types: pageId: type: optional docs: Page ID + branchId: + type: optional + docs: >- + The unique identifier of a [specific page + branch.](https://help.webflow.com/hc/en-us/articles/33961355506195-Page-branching) nodes: optional> pagination: optional + lastUpdated: + type: optional + docs: The date the page dom was most recently updated + access: read-only source: openapi: ../../../openapi/referenced-specs/v2.yml TextNodeWrite: @@ -1214,6 +2115,64 @@ types: type: list source: openapi: ../../../openapi/referenced-specs/v2.yml + SelectNodeWriteChoicesItem: + properties: + value: + type: string + docs: The value of the choice when selected. + text: + type: string + docs: The text to display for the choice. + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + Select: + docs: Update choices on a select node + properties: + nodeId: + type: string + docs: Node UUID + choices: + docs: The list of choices to set on the select node. + type: list + source: + openapi: ../../../openapi/referenced-specs/v2.yml + TextInputNodeWrite: + docs: Update placeholder text on a text input node + properties: + nodeId: + type: string + docs: Node UUID + placeholder: + type: string + docs: The placeholder text of the input node + source: + openapi: ../../../openapi/referenced-specs/v2.yml + SubmitButtonNodeWrite: + docs: Update a submit button node + properties: + nodeId: + type: string + docs: Node UUID + value: + type: optional + docs: The text content of the submit button. + waitingText: + type: optional + docs: The text to show while the form is submitting. + source: + openapi: ../../../openapi/referenced-specs/v2.yml + SearchButtonNodeWrite: + docs: Update a search button node + properties: + nodeId: + type: string + docs: Node UUID + value: + type: string + docs: The text content of the search button. + source: + openapi: ../../../openapi/referenced-specs/v2.yml Component: docs: The Component object properties: @@ -1223,18 +2182,22 @@ types: name: type: optional docs: Component Name + access: read-only group: type: optional docs: The group that the component belongs to + access: read-only description: type: optional docs: Component Description + access: read-only readonly: type: optional docs: >- Indicates whether the component is read-only. Components that cannot be updated within this Site are set to readonly. Workspace Libraries are a good example. + access: read-only source: openapi: ../../../openapi/referenced-specs/v2.yml ComponentList: @@ -1249,8 +2212,8 @@ types: The Component DOM schema represents the content structure of a component. Similar to Page DOM, it captures various content nodes and their associated attributes, but specifically for a component's structure. Each - node has a unique identifier and can contain text, images, or nested - component instances. + node has a unique identifier and can contain text, images, select or text + inputs, submit buttons, or nested component instances. properties: componentId: type: optional @@ -1270,6 +2233,7 @@ types: componentId: type: optional docs: Component ID + access: read-only properties: optional> pagination: optional source: @@ -1314,9 +2278,11 @@ types: lastUpdated: type: optional docs: Date when the Site's scripts were last updated + access: read-only createdOn: type: optional docs: Date when the Site's scripts were created + access: read-only source: openapi: ../../../openapi/referenced-specs/v2.yml CustomCodeHostedResponse: @@ -1325,6 +2291,7 @@ types: id: type: optional docs: Human readable id, derived from the user-specified display name + access: read-only canCopy: type: optional docs: >- @@ -1347,9 +2314,11 @@ types: createdOn: type: optional docs: Timestamp when the script version was created + access: read-only lastUpdated: type: optional docs: Timestamp when the script version was last updated + access: read-only version: type: optional docs: A Semantic Version (SemVer) string, denoting the version of the script @@ -1359,6 +2328,7 @@ types: docs: A list of scripts registered to the site properties: registeredScripts: optional> + pagination: optional source: openapi: ../../../openapi/referenced-specs/v2.yml CustomCodeInlineResponse: @@ -1367,6 +2337,7 @@ types: id: type: optional docs: Human readable id, derived from the user-specified display name + access: read-only canCopy: type: optional docs: >- @@ -1389,9 +2360,11 @@ types: createdOn: type: optional docs: Timestamp when the script version was created + access: read-only lastUpdated: type: optional docs: Timestamp when the script version was last updated + access: read-only version: type: optional docs: A Semantic Version (SemVer) string, denoting the version of the script @@ -1426,9 +2399,11 @@ types: createdOn: type: optional docs: The date the Block was created + access: read-only lastUpdated: type: optional docs: The date the Block was most recently updated + access: read-only source: openapi: ../../../openapi/referenced-specs/v2.yml ListCustomCodeBlocks: @@ -1439,29 +2414,30 @@ types: source: openapi: ../../../openapi/referenced-specs/v2.yml AssetVariant: + docs: Asset variant details properties: hostedUrl: - type: optional + type: string docs: URL of where the asset variant is hosted validation: format: uri originalFileName: - type: optional + type: string docs: Original file name of the variant displayName: - type: optional + type: string docs: Display name of the variant format: - type: optional + type: string docs: format of the variant width: - type: optional + type: integer docs: Width in pixels height: type: optional docs: Height in pixels quality: - type: optional + type: integer docs: Value between 0 and 100 representing the image quality error: type: optional @@ -1469,37 +2445,51 @@ types: source: openapi: ../../../openapi/referenced-specs/v2.yml Asset: + docs: Asset details properties: id: type: optional docs: Unique identifier for this asset + access: read-only contentType: type: optional docs: File format type + access: read-only size: type: optional docs: size in bytes + access: read-only siteId: type: optional docs: Unique identifier for the site that hosts this asset + access: read-only hostedUrl: type: optional docs: Link to the asset validation: format: uri + access: read-only originalFileName: type: optional docs: Original file name at the time of upload + access: read-only displayName: - type: optional + type: string docs: Display name of the asset lastUpdated: type: optional docs: Date the asset metadata was last updated + access: read-only createdOn: type: optional docs: Date the asset metadata was created - variants: optional> + access: read-only + variants: + docs: >- + A list of [asset + variants](https://help.webflow.com/hc/en-us/articles/33961378697107-Responsive-images) + created by Webflow to serve your site responsively. + type: list altText: type: optional docs: The visual description of the asset @@ -1509,6 +2499,7 @@ types: docs: A list of assets properties: assets: optional> + pagination: optional source: openapi: ../../../openapi/referenced-specs/v2.yml AssetUploadUploadDetails: @@ -1610,54 +2601,15 @@ types: - ecomm_new_order - ecomm_order_changed - ecomm_inventory_changed - - user_account_added - - user_account_updated - - user_account_deleted - collection_item_created - collection_item_changed - collection_item_deleted + - collection_item_published - collection_item_unpublished + - comment_created docs: > - * `form_submission` - Sends the [form_submission](#form_submission) event - - * `site_publish` - Sends a [site_publish](#site_publish) event - - * `page_created` - Send the [page_created](#page_created) event - - * `page_metadata_updated` - Sends the - [page_metadata_updated](#page_metadata_updated) event - - * `page_deleted` - Sends the [page_deleted](#page_deleted) event - - * `ecomm_new_order` - Sends the new [ecomm_new_order](#ecomm_new_order) - event - - * `ecomm_order_changed` - Sends the - [ecomm_order_changed](#ecomm_order_changed) event - - * `ecomm_inventory_changed` - Sends the - [ecomm_inventory_changed](#ecomm_inventory_changed) event - - * `user_account_added` - Sends the - [user_account_added](#user_account_added) event - - * `user_account_updated` - Sends the - [user_account_updated](#user_account_updated) event - - * `user_account_deleted` - Sends the - [user_account_deleted](#user_account_deleted) event - - * `collection_item_created` - Sends the - [collection_item_created](#collection_item_created) event - - * `collection_item_changed` - Sends the - [collection_item_changed](#collection_item_changed) event - - * `collection_item_deleted` - Sends the - [collection_item_deleted](#collection_item_deleted) event - - * `collection_item_unpublished` - Sends the - [collection_item_unpublished](#collection_item_unpublished) event + The type of event that triggered the request. See the the documentation + for details on [supported events](/data/reference/all-events). source: openapi: ../../../openapi/referenced-specs/v2.yml WebhookFilter: @@ -1676,6 +2628,7 @@ types: id: type: optional docs: Unique identifier for the Webhook registration + access: read-only triggerType: optional url: type: optional @@ -1683,9 +2636,11 @@ types: workspaceId: type: optional docs: Unique identifier for the Workspace the Webhook is registered in + access: read-only siteId: type: optional docs: Unique identifier for the Site the Webhook is registered in + access: read-only filter: type: optional docs: >- @@ -1694,15 +2649,17 @@ types: lastTriggered: type: optional docs: Date the Webhook instance was last triggered + access: read-only createdOn: type: optional docs: Date the Webhook registration was created + access: read-only source: openapi: ../../../openapi/referenced-specs/v2.yml WebhookList: properties: - pagination: optional webhooks: optional> + pagination: optional source: openapi: ../../../openapi/referenced-specs/v2.yml FormFieldValueType: @@ -1830,175 +2787,6 @@ types: pagination: optional source: openapi: ../../../openapi/referenced-specs/v2.yml - UserDataData: - properties: - name: - type: optional - docs: | - The name of the user - email: - type: optional - docs: | - The email address of the user - accept-privacy: - type: optional - docs: | - Boolean indicating if the user has accepted the privacy policy - accept-communications: - type: optional - docs: | - Boolean indicating if the user has accepted to receive communications - additionalProperties: - type: optional - docs: Custom user attributes - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - UserData: - docs: An object containing the User's basic info and custom fields - properties: - data: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - UserStatus: - enum: - - invited - - verified - - unverified - docs: The status of the user - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - UserAccessGroupsItemType: - enum: - - admin - - ecommerce - docs: | - The type of access group based on how it was assigned to the user. - * `admin` - Assigned to the user via API or in the designer - * `ecommerce` - Assigned to the user via an ecommerce purchase - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml - UserAccessGroupsItem: - docs: Access group slugs and types - properties: - slug: - type: optional - docs: Access group identifier for APIs - type: - type: optional - docs: | - The type of access group based on how it was assigned to the user. - * `admin` - Assigned to the user via API or in the designer - * `ecommerce` - Assigned to the user via an ecommerce purchase - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true - User: - docs: > - The fields that define the schema for a given Item are based on the - Collection that Item belongs to. Beyond the user defined fields, there are - a handful of additional fields that are automatically created for all - items - properties: - id: - type: optional - docs: Unique identifier for the User - isEmailVerified: - type: optional - docs: Shows whether the user has verified their email address - lastUpdated: - type: optional - docs: The timestamp the user was updated - invitedOn: - type: optional - docs: The timestamp the user was invited - createdOn: - type: optional - docs: The timestamp the user was created - lastLogin: - type: optional - docs: The timestamp the user was logged in - status: - type: optional - docs: The status of the user - accessGroups: - type: optional> - docs: Access groups the user belongs to - data: optional - source: - openapi: ../../../openapi/referenced-specs/v2.yml - UserList: - docs: The list users results - properties: - count: - type: optional - docs: Number of users returned - limit: - type: optional - docs: The limit specified in the request - default: 10 - offset: - type: optional - docs: The offset specified for pagination - default: 0 - total: - type: optional - docs: Total number of users in the collection - users: - type: optional> - docs: List of Users for a Site - source: - openapi: ../../../openapi/referenced-specs/v2.yml - UsersNotEnabled: unknown - DuplicateUserEmail: unknown - UserLimitReached: unknown - AccessGroup: - properties: - id: - type: optional - docs: Unique identifier for the Access Group - name: - type: optional - docs: Name of the the Access Group - shortId: - type: optional - docs: >- - Shortened unique identifier based on name, optimized for its use in - the user’s JWT - slug: - type: optional - docs: >- - Shortened unique identifier based on name, optimized for human - readability and public API use - createdOn: - type: optional - docs: The date the Access Group was created - source: - openapi: ../../../openapi/referenced-specs/v2.yml - AccessGroupList: - docs: The list access groups results - properties: - count: - type: optional - docs: Number of access groups returned - limit: - type: optional - docs: The limit specified in the request - default: 10 - offset: - type: optional - docs: The offset specified for pagination - default: 0 - total: - type: optional - docs: Total number of access groups in the collection - accessGroups: - type: optional> - docs: List of Site Access Groups - source: - openapi: ../../../openapi/referenced-specs/v2.yml SkuPropertyListEnumItem: docs: Enumerated Product variants/Options for the SKU properties: @@ -2128,9 +2916,9 @@ types: sku-properties: type: optional> docs: Variant types to include in SKUs - categories: + category: type: optional> - docs: The categories your product belongs to. + docs: The category your product belongs to. tax-category: type: optional docs: Product tax class @@ -2152,18 +2940,23 @@ types: id: type: optional docs: Unique identifier for the Product + access: read-only cmsLocaleId: type: optional docs: Identifier for the locale of the CMS item + access: read-only lastPublished: type: optional docs: The date the Product was last published + access: read-only lastUpdated: type: optional docs: The date the Product was last updated + access: read-only createdOn: type: optional docs: The date the Product was created + access: read-only isArchived: type: optional docs: Boolean determining if the Product is set to archived @@ -2178,8 +2971,10 @@ types: SkuValueList: type: map docs: > - A dictionary that maps a SKU property to a SKU value. The key of the - dictionary is the SKU property ID, and the value is the SKU value ID. + A mapping between SKU properties and their values, represented as + key-value pairs. Each key represents a SKU Property ID (e.g. "color") and + maps to its corresponding SKU Value ID (e.g. "blue"). This structure + defines the specific variant combination for a SKU. SkuFieldDataPrice: docs: price of SKU properties: @@ -2189,6 +2984,9 @@ types: unit: type: optional docs: Currency of Item + currency: + type: optional + docs: Currency of Item (alternative representation) source: openapi: ../../../openapi/referenced-specs/v2.yml inline: true @@ -2209,6 +3007,10 @@ types: - value: one-time name: OneTime - subscription + docs: >- + [Billing + method](https://help.webflow.com/hc/en-us/articles/33961432087955-Add-and-manage-products-and-categories#billing-methods)for + the SKU inline: true source: openapi: ../../../openapi/referenced-specs/v2.yml @@ -2246,6 +3048,10 @@ types: openapi: ../../../openapi/referenced-specs/v2.yml inline: true SkuFieldDataEcSkuSubscriptionPlan: + docs: >- + [Subscription + plan](https://help.webflow.com/hc/en-us/articles/33961432087955-Add-and-manage-products-and-categories#subscription) + for the SKU properties: interval: type: optional @@ -2256,7 +3062,9 @@ types: trial: type: optional docs: Number of days of a trial - plans: optional> + plans: + type: optional> + access: read-only source: openapi: ../../../openapi/referenced-specs/v2.yml inline: true @@ -2276,17 +3084,27 @@ types: compare-at-price: type: optional docs: comparison price of SKU - ec-sku-billing-method: optional - ec-sku-subscription-plan: optional - track-inventory: - type: optional + ec-sku-billing-method: + type: optional docs: >- - A boolean indicating whether inventory for this product should be - tracked. - default: false - quantity: - type: optional - docs: Quantity of SKU that will be tracked as items are ordered. + [Billing + method](https://help.webflow.com/hc/en-us/articles/33961432087955-Add-and-manage-products-and-categories#billing-methods)for + the SKU + ec-sku-subscription-plan: + type: optional + docs: >- + [Subscription + plan](https://help.webflow.com/hc/en-us/articles/33961432087955-Add-and-manage-products-and-categories#subscription) + for the SKU + main-image: + type: optional + docs: The URL for the main image of the SKU + sku: + type: optional + docs: A unique identifier for the SKU + sku-properties: + type: optional> + docs: The properties of the SKU source: openapi: ../../../openapi/referenced-specs/v2.yml Sku: @@ -2295,18 +3113,23 @@ types: id: type: optional docs: Unique identifier for the Product + access: read-only cmsLocaleId: type: optional docs: Identifier for the locale of the CMS item + access: read-only lastPublished: type: optional docs: The date the Product was last published + access: read-only lastUpdated: type: optional docs: The date the Product was last updated + access: read-only createdOn: type: optional docs: The date the Product was created + access: read-only fieldData: optional source: openapi: ../../../openapi/referenced-specs/v2.yml @@ -2472,6 +3295,7 @@ types: productId: type: optional docs: The unique identifier for the Product + access: read-only productName: type: optional docs: User-facing name of the Product @@ -2637,9 +3461,115 @@ types: inline: true source: openapi: ../../../openapi/referenced-specs/v2.yml - OrderCustomerInfo: - docs: An object with the keys `fullName` and `email`. - properties: + OrderShippingAddressType: + enum: + - shipping + - billing + docs: The type of the order address (billing or shipping) + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + OrderShippingAddressJapanType: + enum: + - kana + - kanji + docs: >- + Represents a Japan-only address format. This field will only appear on + orders placed from Japan. + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + OrderShippingAddress: + docs: The shipping address + properties: + type: + type: optional + docs: The type of the order address (billing or shipping) + japanType: + type: optional + docs: >- + Represents a Japan-only address format. This field will only appear on + orders placed from Japan. + addressee: + type: optional + docs: Display name on the address + line1: + type: optional + docs: The first line of the address + line2: + type: optional + docs: The second line of the address + city: + type: optional + docs: The city of the address. + state: + type: optional + docs: The state or province of the address + country: + type: optional + docs: The country of the address + postalCode: + type: optional + docs: The postal code of the address + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + OrderBillingAddressType: + enum: + - shipping + - billing + docs: The type of the order address (billing or shipping) + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + OrderBillingAddressJapanType: + enum: + - kana + - kanji + docs: >- + Represents a Japan-only address format. This field will only appear on + orders placed from Japan. + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + OrderBillingAddress: + docs: The billing address + properties: + type: + type: optional + docs: The type of the order address (billing or shipping) + japanType: + type: optional + docs: >- + Represents a Japan-only address format. This field will only appear on + orders placed from Japan. + addressee: + type: optional + docs: Display name on the address + line1: + type: optional + docs: The first line of the address + line2: + type: optional + docs: The second line of the address + city: + type: optional + docs: The city of the address. + state: + type: optional + docs: The state or province of the address + country: + type: optional + docs: The country of the address + postalCode: + type: optional + docs: The postal code of the address + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + OrderCustomerInfo: + docs: An object with the keys `fullName` and `email`. + properties: fullName: type: optional docs: The full name of the Customer @@ -2725,6 +3655,7 @@ types: The order ID. Will usually be 6 hex characters, but can also be 9 hex characters if the site has a very large number of Orders. Randomly assigned. + access: read-only status: type: optional docs: | @@ -2780,10 +3711,10 @@ types: type: optional> docs: All addresses provided by the customer during the ordering flow. shippingAddress: - type: optional + type: optional docs: The shipping address billingAddress: - type: optional + type: optional docs: The billing address shippingProvider: type: optional @@ -2868,6 +3799,7 @@ types: id: type: optional docs: Unique identifier for a SKU item + access: read-only quantity: type: optional docs: >- @@ -2884,11 +3816,496 @@ types: siteId: type: optional docs: The identifier of the Site + access: read-only createdOn: type: optional docs: Date that the Site was created on + access: read-only defaultCurrency: type: optional docs: The three-letter ISO currency code for the Site source: openapi: ../../../openapi/referenced-specs/v2.yml + FormSubmissionTriggerPayloadSchemaItemFieldType: + enum: + - FormTextInput + - FormTextarea + - FormCheckboxInput + - FormRadioInput + - FormFileUploadInput + docs: Form field type + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + FormSubmissionTriggerPayloadSchemaItem: + properties: + fieldName: + type: optional + docs: Form field name + fieldType: + type: optional + docs: Form field type + fieldElementId: + type: optional + docs: Element ID of the Form Field + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + FormSubmissionTriggerPayload: + docs: The payload of data sent from Webflow + properties: + name: + type: optional + docs: The name of the form + siteId: + type: optional + docs: The ID of the site that the form was submitted from + data: + type: optional> + docs: The data submitted in the form + schema: + type: optional> + docs: A list of fields from the submitted form + submittedAt: + type: optional + docs: The timestamp the form was submitted + id: + type: optional + docs: the ID of the event + formId: + type: optional + docs: The ID of the form submission + formElementId: + type: optional + docs: The uniqueID of the Form element + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + FormSubmissionTrigger: + docs: The Webhook payload for when a form is submitted + properties: + triggerType: + type: optional + docs: The type of event that triggered the request + payload: + type: optional + docs: The payload of data sent from Webflow + source: + openapi: ../../../openapi/referenced-specs/v2.yml + SitePublishPayload: + docs: The payload of data sent from Webflow + properties: + siteId: + type: optional + docs: The ID of the site that was published + publishedOn: + type: optional + docs: The timestamp of the publish event + domains: + type: optional> + docs: The domains that were published + publishedBy: + type: optional> + docs: The name andID of the user who published the site + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + SitePublish: + docs: The Webhook payload for when a Site is published + properties: + triggerType: + type: optional + docs: The type of event that triggered the request + payload: + type: optional + docs: The payload of data sent from Webflow + source: + openapi: ../../../openapi/referenced-specs/v2.yml + NewOrder: + docs: The Webhook payload for when a new order is created + properties: + triggerType: + type: optional + docs: The type of event that triggered the request + payload: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + UpdatedOrder: + docs: The Webhook payload for when an order is updated + properties: + triggerType: + type: optional + docs: The type of event that triggered the request + payload: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + SingleLocaleCreatedPayloadFieldData: + properties: + name: string + slug: string + extra-properties: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + SingleLocaleCreatedPayload: + properties: + id: + type: string + docs: Unique identifier for the Item + validation: + format: uuid + workspaceId: + type: string + docs: Unique identifier of the workspace + validation: + format: uuid + siteId: + type: string + docs: Unique identifier of the site + validation: + format: uuid + collectionId: + type: string + docs: Unique identifier of the collection + validation: + format: uuid + cmsLocaleId: + type: optional + docs: Unique identifier of the CMS locale for this item + validation: + format: uuid + lastPublished: optional + lastUpdated: optional + createdOn: optional + isArchived: optional + isDraft: optional + fieldData: SingleLocaleCreatedPayloadFieldData + source: + openapi: ../../../openapi/referenced-specs/v2.yml + CollectionItemCreated: + docs: The Webhook payload for when a Collection Item is created + properties: + triggerType: + type: literal<"collection_item_created"> + docs: The type of event that triggered the request + payload: + type: SingleLocaleCreatedPayload + source: + openapi: ../../../openapi/referenced-specs/v2.yml + CollectionItemChanged: + docs: The Webhook payload for when a Collection Item is changed + properties: + triggerType: + type: literal<"collection_item_changed"> + docs: The type of event that triggered the request + payload: + type: SingleLocaleCreatedPayload + source: + openapi: ../../../openapi/referenced-specs/v2.yml + CollectionItemRemovedPayloadFieldData: + properties: + name: string + slug: string + extra-properties: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + CollectionItemRemovedPayload: + docs: The payload of data sent from Webflow + properties: + id: + type: optional + docs: The ID of the collection item that was deleted + siteId: + type: optional + docs: The ID of the site + workspaceId: + type: optional + docs: The ID of the workspace + collectionId: + type: optional + docs: The ID of the collection + cmsLocaleId: + type: optional + docs: Unique identifier of the CMS locale for this item + validation: + format: uuid + lastPublished: optional + lastUpdated: optional + createdOn: optional + isArchived: optional + isDraft: optional + fieldData: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + CollectionItemRemoved: + properties: + triggerType: + type: optional + docs: The type of event that triggered the request + payload: + type: optional + docs: The payload of data sent from Webflow + source: + openapi: ../../../openapi/referenced-specs/v2.yml + PayloadFieldData: + properties: + name: string + slug: string + extra-properties: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + Payload: + docs: The payload of data sent from Webflow + properties: + id: + type: optional + docs: The ID of the collection item that was unpublished + siteId: + type: optional + docs: The ID of the site + workspaceId: + type: optional + docs: The ID of the workspace + collectionId: + type: optional + docs: The ID of the collection + cmsLocaleId: + type: optional + docs: Unique identifier of the CMS locale for this item + validation: + format: uuid + lastPublished: optional + lastUpdated: optional + createdOn: optional + isArchived: optional + isDraft: optional + fieldData: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + CollectionItemPublished: + properties: + triggerType: + type: optional + docs: The type of event that triggered the request + payload: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + CollectionItemUnpublishedPayloadFieldData: + properties: + name: string + slug: string + extra-properties: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + CollectionItemUnpublishedPayload: + docs: The payload of data sent from Webflow + properties: + id: + type: optional + docs: The ID of the collection item that was unpublished + siteId: + type: optional + docs: The ID of the site + workspaceId: + type: optional + docs: The ID of the workspace + collectionId: + type: optional + docs: The ID of the collection + cmsLocaleId: + type: optional + docs: Unique identifier of the CMS locale for this item + validation: + format: uuid + lastPublished: optional + lastUpdated: optional + createdOn: optional + isArchived: optional + isDraft: optional + fieldData: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + CollectionItemUnpublished: + properties: + triggerType: + type: optional + docs: The type of event that triggered the request + payload: + type: optional + docs: The payload of data sent from Webflow + source: + openapi: ../../../openapi/referenced-specs/v2.yml + PageCreatedWebhookPayload: + docs: The payload of data sent from Webflow + properties: + siteId: optional + pageId: optional + pageTitle: optional + createdOn: optional + publishedPath: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + PageCreatedWebhook: + docs: The Webhook payload for when a Page is created + properties: + triggerType: + type: optional + docs: The type of event that triggered the request + payload: + type: optional + docs: The payload of data sent from Webflow + source: + openapi: ../../../openapi/referenced-specs/v2.yml + PageMetadataUpdatedWebhookPayload: + docs: The payload of data sent from Webflow + properties: + siteId: optional + pageId: optional + pageTitle: optional + lastUpdated: optional + publishedPath: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + PageMetadataUpdatedWebhook: + docs: The Webhook payload for when a Page's metadata is updated + properties: + triggerType: + type: optional + docs: The type of event that triggered the request + payload: + type: optional + docs: The payload of data sent from Webflow + source: + openapi: ../../../openapi/referenced-specs/v2.yml + PageDeletedWebhookPayload: + docs: The payload of data sent from Webflow + properties: + siteId: optional + pageId: optional + pageTitle: optional + deletedOn: optional + publishedPath: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + PageDeletedWebhook: + docs: The Webhook payload for when a Page is deleted + properties: + triggerType: + type: optional + docs: The type of event that triggered the request + payload: + type: optional + docs: The payload of data sent from Webflow + source: + openapi: ../../../openapi/referenced-specs/v2.yml + CommentPayloadAuthor: + properties: + userId: + type: string + docs: The unique identifier of the author + email: + type: string + docs: Email of the author + name: + type: string + docs: Name of the author + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + CommentPayloadMentionedUsersItem: + properties: + userId: + type: string + docs: The unique identifier of the mentioned user + email: + type: string + docs: Email of the user + name: + type: string + docs: Name of the User + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + CommentPayload: + docs: > + The comment webhook payload contains data for the thread and for replies. + Check the type to determine if the payload is for a thread or a reply. + The webhook payload may be delayed by up to 5 minutes. + properties: + threadId: + type: optional + docs: Unique identifier for the comment thread + access: read-only + commentId: + type: optional + docs: Unique identifier for the comment reply + access: read-only + type: + type: optional + docs: The type of comment payload + access: read-only + siteId: + type: optional + docs: The site unique identifier + access: read-only + pageId: + type: optional + docs: The page unique identifier + access: read-only + localeId: + type: optional + docs: The locale unique identifier + access: read-only + itemId: + type: optional + docs: The item unique identifier + access: read-only + breakpoint: + type: optional + docs: The breakpoint the comment was left on + access: read-only + url: + type: optional + docs: The URL of the page the comment was left on + access: read-only + content: + type: string + docs: The content of the comment reply + isResolved: + type: boolean + docs: Boolean determining if the comment thread is resolved + default: false + author: CommentPayloadAuthor + mentionedUsers: + docs: >- + List of mentioned users. This is an empty array until email + notifications are sent, which can take up to 5 minutes after the + comment is created. + type: list + createdOn: + type: optional + docs: The date the item was created + access: read-only + lastUpdated: + type: optional + docs: The date the item was last updated + access: read-only + source: + openapi: ../../../openapi/referenced-specs/v2.yml + Comment: + docs: The Webhook payload for when a comment thread or reply is made on a Site + properties: + triggerType: + type: optional + docs: The type of event that triggered the request + payload: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/accessGroups.yml b/.mock/definition/accessGroups.yml deleted file mode 100644 index d8828f8..0000000 --- a/.mock/definition/accessGroups.yml +++ /dev/null @@ -1,80 +0,0 @@ -types: - AccessGroupsListRequestSort: - enum: - - value: CreatedOn - name: CreatedOnAscending - docs: Sorts users in ascending order based on their created date - - value: '-CreatedOn' - name: CreatedOnDescending - docs: Sorts users in descending order based on their created date - source: - openapi: ../../../openapi/referenced-specs/v2.yml -imports: - root: __package__.yml -service: - auth: false - base-path: '' - endpoints: - list: - path: /sites/{site_id}/accessgroups - method: GET - auth: true - docs: | - Get a list of access groups for a site - - Required scope | `users:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: List Access Groups - request: - name: AccessGroupsListRequest - query-parameters: - offset: - type: optional - docs: >- - Offset used for pagination if the results have more than limit - records - limit: - type: optional - docs: 'Maximum number of records to be returned (max limit: 100)' - sort: - type: optional - docs: | - Sort string to use when ordering access groups - Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`) - response: - docs: Request was successful - type: root.AccessGroupList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - count: 1 - limit: 10 - offset: 0 - total: 1 - accessGroups: - - id: 62be58d404be8a6cc900c081 - name: Research Team - shortId: rt - slug: hitchhikers-guide-research-team - createdOn: '2022-08-01T19:41:48Z' - - id: 65a96161991e77bbb4a6c573 - name: Admin - shortId: ad - slug: admin - createdOn: '2022-08-01T19:41:48Z' - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/api.yml b/.mock/definition/api.yml index aee9acd..de74f2d 100644 --- a/.mock/definition/api.yml +++ b/.mock/definition/api.yml @@ -3,8 +3,13 @@ error-discrimination: strategy: status-code display-name: Data API environments: - Default: https://api.webflow.com/v2 -default-environment: Default + Data API: + urls: + Base: https://api.webflow.com/v2 + Data API: https://api.webflow.com/v2 + Content Delivery API: https://api-cdn.webflow.com/v2 +default-environment: Data API +default-url: Base auth-schemes: BearerToken: scheme: bearer diff --git a/.mock/definition/assets.yml b/.mock/definition/assets.yml index 35392ec..dcdff94 100644 --- a/.mock/definition/assets.yml +++ b/.mock/definition/assets.yml @@ -7,9 +7,11 @@ service: list: path: /sites/{site_id}/assets method: GET - auth: true + auth: + - OAuth2: + - assets:read docs: | - List assets for a given site + List of assets uploaded to a site Required scope | `assets:read` source: @@ -19,9 +21,21 @@ service: type: string docs: Unique identifier for a Site display-name: List Assets + request: + name: AssetsListRequest + query-parameters: + offset: + type: optional + docs: >- + Offset used for pagination if the results have more than limit + records + limit: + type: optional + docs: 'Maximum number of records to be returned (max limit: 100)' response: docs: Request was successful type: root.Assets + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -31,6 +45,9 @@ service: examples: - path-parameters: site_id: 580e63e98c9a982ac9b8b741 + query-parameters: + offset: 1 + limit: 1 response: body: assets: @@ -55,35 +72,66 @@ service: width: 500 height: 900 quality: 100 - altText: A red chair + altText: A single candy wrapper + - id: 63e5889e7fe4eafa7384cea5 + contentType: image/png + size: 2212772 + siteId: 63938b302ea6b0aa6f3d8745 + hostedUrl: >- + https://s3.amazonaws.com/webflow-prod-assets/63938b302ea6b0aa6f3d8745/63e5889e7fe4eafa7384cea4_Vectors-Wrapper.svg + originalFileName: Gum-Wrapper.svg + displayName: 63e5889e7fe4eafa7384cea5_Gum-Wrapper.png + lastUpdated: '2023-03-01T23:42:57Z' + createdOn: '2023-02-09T23:58:22Z' + variants: + - hostedUrl: >- + https://s3.amazonaws.com/webflow-prod-assets/6258612d1ee792848f805dcf/660d83ce30f3a599ddb0bdb3_Screenshot%202024-03-20%20at%209.03.24%E2%80%AFPM-p-500.png + originalFileName: >- + Screenshot%202024-03-20%20at%209.03.24%E2%80%AFPM-p-500.png + displayName: >- + 660d83ce30f3a599ddb0bdb3_Screenshot%202024-03-20%20at%209.03.24%E2%80%AFPM-p-500.png + format: png + width: 500 + height: 900 + quality: 100 + altText: A single gum wrapper + pagination: + limit: 2 + offset: 0 + total: 2 create: path: /sites/{site_id}/assets method: POST - auth: true + auth: + - OAuth2: + - assets:write docs: > - Create a new asset entry. + The first step in uploading an asset to a site. This endpoint generates a response with the following information: - `uploadUrl` and `uploadDetails`. + `uploadUrl` and `uploadDetails`. - You can use these two properties to [upload the file to Amazon s3 by - making a - POST](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) - request to the `uploadUrl` with the `uploadDetails` object as your - header information in the request. - - Required scope | `assets:write` + Use these properties in the header of a [POST request to Amazson + s3](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) + to complete the upload. + + + + To learn more about how to upload assets to Webflow, see our [assets + guide](/data/docs/working-with-assets). + + Required scope | `assets:write` source: openapi: ../../../openapi/referenced-specs/v2.yml path-parameters: site_id: type: string docs: Unique identifier for a Site - display-name: Create Asset Metadata + display-name: Upload Asset request: name: AssetsCreateRequest body: @@ -103,6 +151,7 @@ service: response: docs: Request was successful type: root.AssetUpload + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -137,16 +186,18 @@ service: assetUrl: >- https://s3.amazonaws.com/webflow-prod-assets/6258612d1ee792848f805dcf/660d907ab9e91e3e9f56385e_paranoidAndroid-2024.png hostedUrl: >- - https://d1otoma47x30pg.cloudfront.net/643021114e290e0d3a0602b2/64358b9544249dc43d37d2b7_Screenshot%202023-04-11%20at%209.50.42%20AM.png + https://dev-assets.website-files.com/643021114e290e0d3a0602b2/64358b9544249dc43d37d2b7_Screenshot%202023-04-11%20at%209.50.42%20AM.png originalFileName: file.png createdOn: '2023-04-11T16:32:21Z' lastUpdated: '2023-04-12T20:31:03Z' get: path: /assets/{asset_id} method: GET - auth: true + auth: + - OAuth2: + - assets:read docs: | - Get an Asset + Get details about an asset Required scope | `assets:read` source: @@ -159,6 +210,7 @@ service: response: docs: Request was successful type: root.Asset + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -170,29 +222,34 @@ service: asset_id: 580e63fc8c9a982ac9b8b745 response: body: - id: 55131cd036c09f7d07883dfc + id: 63e5889e7fe4eafa7384cea4 contentType: image/png - size: 1500 - siteId: 62749158efef318abc8d5a0f - hostedUrl: example.com/hostedimage.png - originalFileName: image.png - displayName: example-image-123.png - lastUpdated: '2016-09-06T21:12:22Z' - createdOn: '2016-09-02T23:26:22Z' + size: 2212772 + siteId: 63938b302ea6b0aa6f3d8745 + hostedUrl: >- + https://s3.amazonaws.com/webflow-prod-assets/63938b302ea6b0aa6f3d8745/63e5889e7fe4eafa7384cea4_Vectors-Wrapper.svg + originalFileName: Candy-Wrapper.svg + displayName: 63e5889e7fe4eafa7384cea4_Candy-Wrapper.png + lastUpdated: '2023-03-01T23:42:57Z' + createdOn: '2023-02-09T23:58:22Z' variants: - - hostedUrl: example.com/hostedimage.png - originalFileName: image.png - displayName: A brown dog - format: format - width: 1500 + - hostedUrl: >- + https://s3.amazonaws.com/webflow-prod-assets/6258612d1ee792848f805dcf/660d83ce30f3a599ddb0bdb3_Screenshot%202024-03-20%20at%209.03.24%E2%80%AFPM-p-500.png + originalFileName: Screenshot%202024-03-20%20at%209.03.24%E2%80%AFPM-p-500.png + displayName: >- + 660d83ce30f3a599ddb0bdb3_Screenshot%202024-03-20%20at%209.03.24%E2%80%AFPM-p-500.png + format: png + width: 500 height: 900 - quality: 1 + quality: 100 error: error - altText: A red chair + altText: A single candy wrapper delete: path: /assets/{asset_id} method: DELETE - auth: true + auth: + - OAuth2: + - assets:write docs: | Delete an Asset @@ -216,9 +273,11 @@ service: update: path: /assets/{asset_id} method: PATCH - auth: true + auth: + - OAuth2: + - assets:write docs: | - Update an Asset + Update details of an Asset. Required scope | `assets:write` source: @@ -244,6 +303,7 @@ service: response: docs: Request was successful type: root.Asset + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -256,29 +316,34 @@ service: request: {} response: body: - id: 55131cd036c09f7d07883dfc + id: 63e5889e7fe4eafa7384cea4 contentType: image/png - size: 1500 - siteId: 62749158efef318abc8d5a0f - hostedUrl: example.com/hostedimage.png - originalFileName: image.png - displayName: example-image-123.png - lastUpdated: '2016-09-06T21:12:22Z' - createdOn: '2016-09-02T23:26:22Z' + size: 2212772 + siteId: 63938b302ea6b0aa6f3d8745 + hostedUrl: >- + https://s3.amazonaws.com/webflow-prod-assets/63938b302ea6b0aa6f3d8745/63e5889e7fe4eafa7384cea4_Vectors-Wrapper.svg + originalFileName: Candy-Wrapper.svg + displayName: 63e5889e7fe4eafa7384cea4_Candy-Wrapper.png + lastUpdated: '2023-03-01T23:42:57Z' + createdOn: '2023-02-09T23:58:22Z' variants: - - hostedUrl: example.com/hostedimage.png - originalFileName: image.png - displayName: A brown dog - format: format - width: 1500 + - hostedUrl: >- + https://s3.amazonaws.com/webflow-prod-assets/6258612d1ee792848f805dcf/660d83ce30f3a599ddb0bdb3_Screenshot%202024-03-20%20at%209.03.24%E2%80%AFPM-p-500.png + originalFileName: Screenshot%202024-03-20%20at%209.03.24%E2%80%AFPM-p-500.png + displayName: >- + 660d83ce30f3a599ddb0bdb3_Screenshot%202024-03-20%20at%209.03.24%E2%80%AFPM-p-500.png + format: png + width: 500 height: 900 - quality: 1 + quality: 100 error: error - altText: A red chair + altText: A single candy wrapper list-folders: path: /sites/{site_id}/asset_folders method: GET - auth: true + auth: + - OAuth2: + - assets:read docs: | List Asset Folders within a given site @@ -293,6 +358,7 @@ service: response: docs: Request was successful type: root.AssetFolderList + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -321,7 +387,9 @@ service: create-folder: path: /sites/{site_id}/asset_folders method: POST - auth: true + auth: + - OAuth2: + - assets:write docs: | Create an Asset Folder within a given site @@ -349,6 +417,7 @@ service: response: docs: Request was successful type: root.AssetFolder + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -374,7 +443,9 @@ service: get-folder: path: /asset_folders/{asset_folder_id} method: GET - auth: true + auth: + - OAuth2: + - assets:read docs: | Get details about a specific Asset Folder @@ -389,6 +460,7 @@ service: response: docs: Request was successful type: root.AssetFolder + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError diff --git a/.mock/definition/collections.yml b/.mock/definition/collections.yml index 661b54b..b9ee7cd 100644 --- a/.mock/definition/collections.yml +++ b/.mock/definition/collections.yml @@ -7,7 +7,9 @@ service: list: path: /sites/{site_id}/collections method: GET - auth: true + auth: + - OAuth2: + - cms:read docs: | List of all Collections within a Site. @@ -22,6 +24,7 @@ service: response: docs: Request was successful type: root.CollectionList + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -55,9 +58,19 @@ service: create: path: /sites/{site_id}/collections method: POST - auth: true - docs: | - Create a Collection for a site. + auth: + - OAuth2: + - cms:write + docs: > + Create a Collection for a site with collection fields. + + + Each collection includes the required _name_ and _slug_ fields, which + are generated automatically. You can update the `displayName` of these + fields, but the slug for them cannot be changed. Fields slugs are + automatically converted to lowercase. Spaces in slugs are replaced with + hyphens. + Required scope | `cms:write` source: @@ -80,14 +93,19 @@ service: slug: type: optional docs: Part of a URL that identifier + fields: + type: optional> + docs: An array of custom fields to add to the collection content-type: application/json response: docs: Request was successful type: root.Collection + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError - root.NotFoundError + - root.ConflictError - root.TooManyRequestsError - root.InternalServerError examples: @@ -97,26 +115,57 @@ service: displayName: Blog Posts singularName: Blog Post slug: posts + fields: + - isRequired: true + type: PlainText + displayName: Title + helpText: The title of the blog post + - isRequired: true + type: RichText + displayName: Content + helpText: The content of the blog post + - isRequired: true + type: Reference + displayName: Author + helpText: The author of the blog post + metadata: + collectionId: 23cc2d952d4e4631ffd4345d2743db4e response: body: - id: 580e63fc8c9a982ac9b8b745 + id: 562ac0395358780a1f5e6fbd displayName: Blog Posts singularName: Blog Post - slug: post + slug: posts createdOn: '2016-10-24T19:41:48Z' lastUpdated: '2016-10-24T19:42:38Z' fields: - - id: 23cc2d952d4e4631ffd4345d2743db4e + - id: id isRequired: true isEditable: true type: PlainText - slug: name - displayName: Name - helpText: helpText + slug: title + displayName: Title + helpText: The title of the blog post + - id: id + isRequired: true + isEditable: true + type: RichText + slug: content + displayName: Content + helpText: The content of the blog post + - id: id + isRequired: true + isEditable: true + type: Reference + slug: author + displayName: Author + helpText: The author of the blog post get: path: /collections/{collection_id} method: GET - auth: true + auth: + - OAuth2: + - cms:read docs: | Get the full details of a collection from its ID. @@ -131,6 +180,7 @@ service: response: docs: Request was successful type: root.Collection + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -142,24 +192,138 @@ service: collection_id: 580e63fc8c9a982ac9b8b745 response: body: - id: 580e63fc8c9a982ac9b8b745 - displayName: Blog Posts - singularName: Blog Post - slug: post - createdOn: '2016-10-24T19:41:48Z' - lastUpdated: '2016-10-24T19:42:38Z' + id: 7f15043107e2fc95644e93807ee25dd6 + displayName: Guide Entries + singularName: Guide Entry + slug: guide-entry + createdOn: '2024-04-12T12:42:00Z' + lastUpdated: '2024-04-12T12:42:00Z' fields: - - id: 23cc2d952d4e4631ffd4345d2743db4e + - id: 5e2a1b3c4d5e6f7890a1b2c3 isRequired: true isEditable: true type: PlainText slug: name - displayName: Name + displayName: Entry Title + helpText: Name of the entry. + - id: 5e2a1b3c4d5e6f7890a1b2c4 + isRequired: true + isEditable: true + type: PlainText + slug: slug + displayName: Slug + helpText: Slug of the entry. + - id: 6f7e8d9c0b1a2e3d4c5b6a7f + isRequired: false + isEditable: true + type: PlainText + slug: summary + displayName: Summary + helpText: A short summary of the entry. + - id: 1a2b3c4d5e6f7a8b9c0d1e2f + isRequired: false + isEditable: true + type: RichText + slug: entry-html + displayName: Entry HTML + helpText: The HTML content of the entry. + - id: 7e8d9c0b1a2e3d4c5b6a7f8e + isRequired: false + isEditable: true + type: Image + slug: illustration-image + displayName: Illustration Image + helpText: An image of the entry. + - id: 2f3e4d5c6b7a8e9d0c1b2a3f + isRequired: false + isEditable: true + type: VideoLink + slug: demonstration-video + displayName: Demonstration Video + helpText: A video of the entry. + - id: 8e9d0c1b2a3f4e5d6c7b8a9e + isRequired: false + isEditable: true + type: Link + slug: more-info-link + displayName: More Info Link + helpText: A link to more information about the entry. + - id: 3f4e5d6c7b8a9e0d1c2b3a4f + isRequired: false + isEditable: true + type: Number + slug: importance-level + displayName: Importance Level + helpText: The importance level of the entry. + - id: 9e0d1c2b3a4f5e6d7c8b9a0e + isRequired: false + isEditable: true + type: Switch + slug: is-essential + displayName: Is Essential + helpText: Is this entry essential? + - id: 4f5e6d7c8b9a0e1d2c3b4a5f + isRequired: false + isEditable: true + type: Color + slug: first-mentioned + displayName: First Mentioned + helpText: Date of the first mention of the subject. + - id: 0e1d2c3b4a5f6e7d8c9b0a1e + isRequired: false + isEditable: true + type: Color + slug: towel-color + displayName: Towel Color + helpText: The color of the towel. + - id: 5f6e7d8c9b0a1e2d3c4b5a6f + isRequired: false + isEditable: true + type: Reference + slug: related-entry + displayName: Related Entry + helpText: A related entry. + - id: 1e2d3c4b5a6f7e8d9c0b1a2f + isRequired: false + isEditable: true + type: MultiReference + slug: mentioned-in-entries + displayName: Mentioned In Entries + helpText: Entries that mention this subject. + - id: 6f7e8d9c0b1a2e3d4c5b6a8f + isRequired: false + isEditable: true + type: Option + slug: item-type + displayName: Item Type + helpText: The type of item. + - id: 2e3d4c5b6a7f8e9d0c1b2a4f + isRequired: false + isEditable: true + type: File + slug: guide-file + displayName: Guide File + helpText: helpText + - id: 7f8e9d0c1b2a3f4e5d6c8b9e + isRequired: false + isEditable: true + type: Email + slug: contributor-email + displayName: Contributor Email + helpText: helpText + - id: 3a4f5e6d7c8b9a0e1d2c4b5f + isRequired: false + isEditable: true + type: Phone + slug: emergency-contact + displayName: Emergency Contact helpText: helpText delete: path: /collections/{collection_id} method: DELETE - auth: true + auth: + - OAuth2: + - cms:write docs: | Delete a collection using its ID. diff --git a/.mock/definition/collections/fields.yml b/.mock/definition/collections/fields.yml index 08dc554..8d83b9f 100644 --- a/.mock/definition/collections/fields.yml +++ b/.mock/definition/collections/fields.yml @@ -1,24 +1,3 @@ -types: - FieldCreateType: - enum: - - Color - - DateTime - - Email - - ExtFileRef - - File - - Image - - Link - - MultiImage - - Number - - Phone - - PlainText - - RichText - - Switch - - Video - docs: Choose these appropriate field type for your collection data - inline: true - source: - openapi: ../../../openapi/referenced-specs/v2.yml imports: root: ../__package__.yml service: @@ -28,22 +7,19 @@ service: create: path: /collections/{collection_id}/fields method: POST - auth: true + auth: + - OAuth2: + - cms:write docs: > - Create a custom field in a collection. + Create a custom field in a collection. - Slugs must be all lowercase letters without spaces. + Field validation is currently not available through the API. - If you pass a string with uppercase letters and/or spaces to the "Slug" - property, Webflow will - convert the slug to lowercase and replace spaces with "-." - - - Only some field types can be created through the API. - - This endpoint does not currently support bulk creation. + Bulk creation of fields is not supported with this endpoint. To add + multiple fields at once, include them when you [create the + collection.](/data/v2.0.0/reference/cms/collections/create) Required scope | `cms:write` @@ -55,52 +31,94 @@ service: docs: Unique identifier for a Collection display-name: Create Collection Field request: - name: FieldCreate - body: - properties: - isRequired: - type: optional - docs: define whether a field is required in a collection - type: - type: FieldCreateType - docs: Choose these appropriate field type for your collection data - displayName: - type: string - docs: The name of a field - helpText: - type: optional - docs: Additional text to help anyone filling out this field + body: root.FieldCreate content-type: application/json response: docs: Request was successful - type: root.Field + type: root.FieldCreate + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError - root.NotFoundError + - root.ConflictError - root.TooManyRequestsError - root.InternalServerError examples: - - path-parameters: + - name: StaticField + path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 request: + id: 562ac0395358780a1f5e6fbc + isEditable: true isRequired: false type: RichText displayName: Post Body helpText: Add the body of your post here response: body: - id: 75821f618da60c18383330bcc0ca488b - isRequired: false + id: 562ac0395358780a1f5e6fbc isEditable: true + isRequired: false type: RichText - slug: post-body displayName: Post Body helpText: Add the body of your post here + - name: OptionField + path-parameters: + collection_id: 580e63fc8c9a982ac9b8b745 + request: + id: 562ac0395358780a1f5e6fbc + isEditable: true + isRequired: false + type: Option + displayName: Post Type + helpText: Add the body of your post here + metadata: + options: + - name: Feature + - name: News + - name: Product Highlight + response: + body: + id: 562ac0395358780a1f5e6fbc + isEditable: true + isRequired: false + type: Option + displayName: Post Type + helpText: Add the body of your post here + metadata: + options: + - name: Feature + - name: News + - name: Product Highlight + - name: ReferenceField + path-parameters: + collection_id: 580e63fc8c9a982ac9b8b745 + request: + id: 562ac0395358780a1f5e6fbd + isEditable: true + isRequired: false + type: Reference + displayName: Author + helpText: Add the post author here + metadata: + collectionId: 63692ab61fb2852f582ba8f5 + response: + body: + id: 562ac0395358780a1f5e6fbd + isEditable: true + isRequired: false + type: Reference + displayName: Author + helpText: Add the post author here + metadata: + collectionId: 63692ab61fb2852f582ba8f5 delete: path: /collections/{collection_id}/fields/{field_id} method: DELETE - auth: true + auth: + - OAuth2: + - cms:write docs: > Delete a custom field in a collection. This endpoint does not currently support bulk deletion. @@ -130,7 +148,9 @@ service: update: path: /collections/{collection_id}/fields/{field_id} method: PATCH - auth: true + auth: + - OAuth2: + - cms:write docs: | Update a custom field in a collection. @@ -162,6 +182,7 @@ service: response: docs: Request was successful type: root.Field + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -185,5 +206,7 @@ service: slug: post-body displayName: Post Body helpText: Add the body of your post here + validations: + additionalProperties: additionalProperties source: openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/collections/items.yml b/.mock/definition/collections/items.yml index f765817..57e6402 100644 --- a/.mock/definition/collections/items.yml +++ b/.mock/definition/collections/items.yml @@ -1,3 +1,5 @@ +imports: + root: ../__package__.yml types: ItemsListItemsRequestSortBy: enum: @@ -20,11 +22,11 @@ types: source: openapi: ../../../openapi/referenced-specs/v2.yml inline: true - ItemsCreateItemRequest: + ItemsCreateItemRequestBody: discriminated: false union: - root.CollectionItemPostSingle - - Multiple Items + - type: Multiple Items source: openapi: ../../../openapi/referenced-specs/v2.yml ItemsDeleteItemsRequestItemsItem: @@ -38,6 +40,13 @@ types: source: openapi: ../../../openapi/referenced-specs/v2.yml inline: true + ItemsUpdateItemsResponse: + discriminated: false + union: + - type: root.CollectionItem + - type: root.CollectionItemList + source: + openapi: ../../../openapi/referenced-specs/v2.yml ItemsListItemsLiveRequestSortBy: enum: - lastPublished @@ -59,16 +68,16 @@ types: source: openapi: ../../../openapi/referenced-specs/v2.yml inline: true - ItemsCreateItemLiveRequest: + ItemsCreateItemLiveRequestBody: discriminated: false union: - - root.CollectionItem - - Multiple Live Items + - type: root.CollectionItem + - type: Multiple Live Items source: openapi: ../../../openapi/referenced-specs/v2.yml ItemsDeleteItemsLiveRequestItemsItem: properties: - itemId: + id: type: string docs: Unique identifier for the Item cmsLocaleIds: @@ -113,20 +122,52 @@ types: CreateBulkCollectionItemRequestBodyFieldData: discriminated: false union: - - Single CMS Item + - type: Single CMS Item - docs: A list of CMS items to create type: list source: openapi: ../../../openapi/referenced-specs/v2.yml inline: true + Item IDs: + docs: An array of Item IDs in a single locale + properties: + itemIds: optional> + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + ItemsPublishItemRequestItemsItemsItem: + properties: + id: + type: string + docs: The ID of the CMS item + cmsLocaleIds: + type: optional> + docs: Array of identifiers for the locales where the item will be published + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + Item IDs with Locales: + docs: An array of Item IDs with included `cmsLocaleIds` + properties: + items: optional> + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + ItemsPublishItemRequest: + discriminated: false + union: + - type: Item IDs + docs: An array of Item IDs in a single locale + - type: Item IDs with Locales + docs: An array of Item IDs with included `cmsLocaleIds` + source: + openapi: ../../../openapi/referenced-specs/v2.yml ItemsPublishItemResponse: properties: publishedItemIds: optional> errors: optional> source: openapi: ../../../openapi/referenced-specs/v2.yml -imports: - root: ../__package__.yml service: auth: false base-path: '' @@ -134,7 +175,9 @@ service: list-items: path: /collections/{collection_id}/items method: GET - auth: true + auth: + - OAuth2: + - cms:read docs: | List of all Items within a Collection. @@ -157,19 +200,22 @@ service: response. To query multiple locales, input a comma separated string. offset: - type: optional + type: optional docs: >- Offset used for pagination if the results have more than limit records limit: - type: optional + type: optional docs: 'Maximum number of records to be returned (max limit: 100)' name: type: optional - docs: The name of the item(s) + docs: Filter by the exact name of the item(s) slug: type: optional - docs: The slug of the item + docs: Filter by the exact slug of the item + lastPublished: + type: optional + docs: Filter by the last published date of the item(s) sortBy: type: optional docs: Sort results by the provided value @@ -179,6 +225,7 @@ service: response: docs: Request was successful type: root.CollectionItemList + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -188,6 +235,14 @@ service: examples: - path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 + query-parameters: + cmsLocaleId: cmsLocaleId + offset: 1 + limit: 1 + name: name + slug: slug + sortBy: lastPublished + sortOrder: asc response: body: items: @@ -222,14 +277,16 @@ service: create-item: path: /collections/{collection_id}/items method: POST - auth: true + auth: + - OAuth2: + - cms:write docs: > Create Item(s) in a Collection. To create items across multiple locales, please use [this - endpoint.](/v2.0.0/data/reference/cms/collection-items/staged-items/create-items) + endpoint.](/data/reference/cms/collection-items/staged-items/create-items) Required scope | `CMS:write` @@ -241,11 +298,20 @@ service: docs: Unique identifier for a Collection display-name: Create Collection Item(s) request: - body: ItemsCreateItemRequest + body: ItemsCreateItemRequestBody + query-parameters: + skipInvalidFiles: + type: optional + default: true + docs: >- + When true, invalid files are skipped and processing continues. + When false, the entire request fails if any file is invalid. + name: ItemsCreateItemRequest content-type: application/json response: docs: Request was successful type: root.CollectionItem + status-code: 202 errors: - root.BadRequestError - root.UnauthorizedError @@ -256,15 +322,44 @@ service: - name: SingleItem path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 + query-parameters: + skipInvalidFiles: true request: isArchived: false isDraft: false fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - date: '2022-11-18T00:00:00.000Z' - featured: true - color: '#db4b68' + name: The Hitchhiker's Guide to the Galaxy + slug: hitchhikers-guide-to-the-galaxy + plain-text: Don't Panic. + rich-text: >- +

A Guide to Interstellar Travel

A towel is about the + most massively useful thing an interstellar hitchhiker can have. + Don't forget yours!

+ main-image: + fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + image-gallery: + - fileId: 62b720ef280c7a7a3be8cabd + url: /files/62b720ef280c7a7a3be8cabd_image.png + - fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + intro-video: https://www.youtube.com/watch?v=aJ83KAggd-4 + official-site: >- + https://hitchhikers.fandom.com/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy + contact-email: zaphod.beeblebrox@heartofgold.gov + support-phone: 424-242-4242 + answer-to-everything: 42 + release-date: '1979-10-12T00:00:00.000Z' + is-featured: true + brand-color: '#000000' + category: 62b720ef280c7a7a3be8cabf + author: 62b720ef280c7a7a3be8cab0 + tags: + - 62b720ef280c7a7a3be8cab1 + - 62b720ef280c7a7a3be8cab2 + downloadable-asset: + fileId: 62b720ef280c7a7a3be8cab3 + url: /files/62b720ef280c7a7a3be8cab3_document.pdf response: body: id: 42b720ef280c7a7a3be8cabe @@ -275,14 +370,43 @@ service: isArchived: false isDraft: false fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - color: '#db4b68' - date: '2022-11-18T00:00:00.000Z' - featured: true + name: The Hitchhiker's Guide to the Galaxy + slug: hitchhikers-guide-to-the-galaxy + plain-text: Don't Panic. + rich-text: >- +

A Guide to Interstellar Travel

A towel is about the + most massively useful thing an interstellar hitchhiker can + have. Don't forget yours!

+ main-image: + fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + image-gallery: + - fileId: 62b720ef280c7a7a3be8cabd + url: /files/62b720ef280c7a7a3be8cabd_image.png + - fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + intro-video: https://www.youtube.com/watch?v=aJ83KAggd-4 + official-site: >- + https://hitchhikers.fandom.com/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy + contact-email: zaphod.beeblebrox@heartofgold.gov + support-phone: 424-242-4242 + answer-to-everything: 42 + release-date: '1979-10-12T00:00:00.000Z' + is-featured: true + brand-color: '#000000' + category: 62b720ef280c7a7a3be8cabf + author: 62b720ef280c7a7a3be8cab0 + tags: + - 62b720ef280c7a7a3be8cab1 + - 62b720ef280c7a7a3be8cab2 + downloadable-asset: + fileId: 62b720ef280c7a7a3be8cab3 + url: /files/62b720ef280c7a7a3be8cab3_document.pdf - name: MultipleItems path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 + query-parameters: + skipInvalidFiles: true request: items: - isArchived: false @@ -317,13 +441,15 @@ service: delete-items: path: /collections/{collection_id}/items method: DELETE - auth: true + auth: + - OAuth2: + - cms:write docs: > Delete Items from a Collection. - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the - items are localized, items will be deleted only in the primary locale. + Items will only be deleted in the primary + locale unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -338,7 +464,7 @@ service: name: ItemsDeleteItemsRequest body: properties: - items: optional> + items: list content-type: application/json errors: - root.BadRequestError @@ -350,17 +476,24 @@ service: examples: - path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 - request: {} + request: + items: + - id: 580e64008c9a982ac9b8b754 update-items: path: /collections/{collection_id}/items method: PATCH - auth: true + auth: + - OAuth2: + - cms:write docs: > - Update a single item or multiple items (up to 100) in a Collection. + Update a single item or multiple items in a Collection. + + The limit for this endpoint is 100 items. - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the - items are localized, items will be updated only in the primary locale. + + Items will only be updated in the primary + locale, unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -373,13 +506,21 @@ service: display-name: Update Collection Items request: name: ItemsUpdateItemsRequest + query-parameters: + skipInvalidFiles: + type: optional + default: true + docs: >- + When true, invalid files are skipped and processing continues. + When false, the entire request fails if any file is invalid. body: properties: items: optional> content-type: application/json response: docs: Request was successful - type: root.CollectionItem + type: ItemsUpdateItemsResponse + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -390,6 +531,8 @@ service: - name: LocalizedItems path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 + query-parameters: + skipInvalidFiles: true request: items: - id: 66f6ed9576ddacf3149d5ea6 @@ -418,22 +561,60 @@ service: featured: false response: body: - id: id - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2023-03-17T18:47:35.560Z' - createdOn: '2023-03-17T18:47:35.560Z' - isArchived: true - isDraft: true - fieldData: - name: My new item - slug: my-new-item - date: '2022-11-18T00:00:00.000Z' - featured: false - color: '#db4b68' + items: + - id: 66f6ed9576ddacf3149d5ea6 + cmsLocaleId: 66f6e966c9e1dc700a857ca5 + lastPublished: '2024-09-27T17:38:29.066Z' + lastUpdated: '2024-09-27T17:38:29.066Z' + createdOn: '2024-09-27T17:38:29.066Z' + isArchived: false + isDraft: false + fieldData: + name: Ne Paniquez Pas + slug: ne-paniquez-pas + featured: false + - id: 66f6ed9576ddacf3149d5ea6 + cmsLocaleId: 66f6e966c9e1dc700a857ca4 + lastPublished: '2024-09-27T17:38:29.066Z' + lastUpdated: '2024-09-27T17:38:29.066Z' + createdOn: '2024-09-27T17:38:29.066Z' + isArchived: false + isDraft: false + fieldData: + name: No Entrar en Pánico + slug: no-entrar-en-panico + featured: false + - id: 66f6ed9576ddacf3149d5eaa + cmsLocaleId: 66f6e966c9e1dc700a857ca5 + lastPublished: '2024-09-27T17:38:29.066Z' + lastUpdated: '2024-09-27T17:38:29.066Z' + createdOn: '2024-09-27T17:38:29.066Z' + isArchived: false + isDraft: false + fieldData: + name: Au Revoir et Merci pour Tous les Poissons + slug: au-revoir-et-merci + featured: false + - id: 66f6ed9576ddacf3149d5eaa + cmsLocaleId: 66f6e966c9e1dc700a857ca4 + lastPublished: '2024-09-27T17:38:29.066Z' + lastUpdated: '2024-09-27T17:38:29.066Z' + createdOn: '2024-09-27T17:38:29.066Z' + isArchived: false + isDraft: false + fieldData: + name: Hasta Luego y Gracias por Todo el Pescado + slug: hasta-luego-y-gracias + featured: false + pagination: + limit: 25 + offset: 0 + total: 4 - name: MultipleItems path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 + query-parameters: + skipInvalidFiles: true request: items: - id: 580e64008c9a982ac9b8b754 @@ -454,113 +635,47 @@ service: department: Product response: body: - id: id - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2023-03-17T18:47:35.560Z' - createdOn: '2023-03-17T18:47:35.560Z' - isArchived: true - isDraft: true - fieldData: - name: My new item - slug: my-new-item - date: '2022-11-18T00:00:00.000Z' - featured: false - color: '#db4b68' - - name: Multiple items updated across multiple locales - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - items: - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - fieldData: - name: Ne Paniquez Pas - slug: ne-paniquez-pas - featured: false - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - fieldData: - name: No Entrar en Pánico - slug: no-entrar-en-panico - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - fieldData: - name: Au Revoir et Merci pour Tous les Poissons - slug: au-revoir-et-merci - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - fieldData: - name: Hasta Luego y Gracias por Todo el Pescado - slug: hasta-luego-y-gracias - featured: false - response: - body: - id: id - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2023-03-17T18:47:35.560Z' - createdOn: '2023-03-17T18:47:35.560Z' - isArchived: true - isDraft: true - fieldData: - name: My new item - slug: my-new-item - date: '2022-11-18T00:00:00.000Z' - featured: false - color: '#db4b68' - - name: Mulitple items updated in a single locale - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - request: - items: - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - fieldData: - name: Ne Paniquez Pas - slug: ne-paniquez-pas - featured: false - - id: 66f6ed9576ddacf3149d5ea6 - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - fieldData: - name: No Entrar en Pánico - slug: no-entrar-en-panico - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca5 - fieldData: - name: Au Revoir et Merci pour Tous les Poissons - slug: au-revoir-et-merci - featured: false - - id: 66f6ed9576ddacf3149d5eaa - cmsLocaleId: 66f6e966c9e1dc700a857ca4 - fieldData: - name: Hasta Luego y Gracias por Todo el Pescado - slug: hasta-luego-y-gracias - featured: false - response: - body: - id: id - cmsLocaleId: 653ad57de882f528b32e810e - lastPublished: '2023-03-17T18:47:35.560Z' - lastUpdated: '2023-03-17T18:47:35.560Z' - createdOn: '2023-03-17T18:47:35.560Z' - isArchived: true - isDraft: true - fieldData: - name: My new item - slug: my-new-item - date: '2022-11-18T00:00:00.000Z' - featured: false - color: '#db4b68' + items: + - id: 62b720ef280c7a7a3be8cabe + cmsLocaleId: 66f6e966c9e1dc700a857ca3 + lastPublished: '2022-06-30T13:35:20.878Z' + lastUpdated: '2022-06-25T14:51:27.809Z' + createdOn: '2022-06-25T14:51:27.809Z' + isArchived: false + isDraft: false + fieldData: + name: Senior Data Analyst + slug: senior-data-analyst + url: https://boards.greenhouse.io/webflow/jobs/26567701 + department: Data + - id: 62c880ef281c7b7b4cf9dabc + cmsLocaleId: 66f6e966c9e1dc700a857ca3 + lastPublished: '2023-04-15T10:25:18.123Z' + lastUpdated: '2023-04-10T11:45:30.567Z' + createdOn: '2023-04-10T11:45:30.567Z' + isArchived: false + isDraft: false + fieldData: + name: Product Manager + slug: product-manager + url: https://boards.greenhouse.io/webflow/jobs/31234567 + department: Product + pagination: + limit: 25 + offset: 0 + total: 2 list-items-live: path: /collections/{collection_id}/items/live method: GET - auth: true + auth: + - OAuth2: + - cms:read docs: | - List of all live Items within a Collection. + List all published items in a collection. + + + Serving data to applications in real-time? Use the Content Delivery API at `api-cdn.webflow.com` for better performance. The CDN-backed endpoint is optimized for high-volume reads, while the Data API is designed for writes and management operations. + Required scope | `CMS:read` source: @@ -581,19 +696,22 @@ service: response. To query multiple locales, input a comma separated string. offset: - type: optional + type: optional docs: >- Offset used for pagination if the results have more than limit records limit: - type: optional + type: optional docs: 'Maximum number of records to be returned (max limit: 100)' name: type: optional - docs: The name of the item(s) + docs: Filter by the exact name of the item(s) slug: type: optional - docs: The slug of the item + docs: Filter by the exact slug of the item + lastPublished: + type: optional + docs: Filter by the last published date of the item(s) sortBy: type: optional docs: Sort results by the provided value @@ -603,6 +721,8 @@ service: response: docs: Request was successful type: root.CollectionItemList + status-code: 200 + url: Data API errors: - root.BadRequestError - root.UnauthorizedError @@ -612,6 +732,14 @@ service: examples: - path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 + query-parameters: + cmsLocaleId: cmsLocaleId + offset: 1 + limit: 1 + name: name + slug: slug + sortBy: lastPublished + sortOrder: asc response: body: items: @@ -646,15 +774,17 @@ service: create-item-live: path: /collections/{collection_id}/items/live method: POST - auth: true + auth: + - OAuth2: + - cms:write docs: > - Create live Item(s) in a Collection. The Item(s) will be published to - the live site. + Create item(s) in a collection that will be immediately published to the + live site. To create items across multiple locales, [please use this - endpoint.](/v2.0.0/data/reference/cms/collection-items/staged-items/create-items) + endpoint.](/data/reference/cms/collection-items/staged-items/create-items) @@ -667,11 +797,20 @@ service: docs: Unique identifier for a Collection display-name: Create Live Collection Item(s) request: - body: ItemsCreateItemLiveRequest + body: ItemsCreateItemLiveRequestBody + query-parameters: + skipInvalidFiles: + type: optional + default: true + docs: >- + When true, invalid files are skipped and processing continues. + When false, the entire request fails if any file is invalid. + name: ItemsCreateItemLiveRequest content-type: application/json response: docs: Request was successful type: root.CollectionItem + status-code: 202 errors: - root.BadRequestError - root.UnauthorizedError @@ -682,15 +821,44 @@ service: - name: SingleItem path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 + query-parameters: + skipInvalidFiles: true request: isArchived: false isDraft: false fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - date: '2022-11-18T00:00:00.000Z' - featured: true - color: '#db4b68' + name: The Hitchhiker's Guide to the Galaxy + slug: hitchhikers-guide-to-the-galaxy + plain-text: Don't Panic. + rich-text: >- +

A Guide to Interstellar Travel

A towel is about the + most massively useful thing an interstellar hitchhiker can have. + Don't forget yours!

+ main-image: + fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + image-gallery: + - fileId: 62b720ef280c7a7a3be8cabd + url: /files/62b720ef280c7a7a3be8cabd_image.png + - fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + intro-video: https://www.youtube.com/watch?v=aJ83KAggd-4 + official-site: >- + https://hitchhikers.fandom.com/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy + contact-email: zaphod.beeblebrox@heartofgold.gov + support-phone: 424-242-4242 + answer-to-everything: 42 + release-date: '1979-10-12T00:00:00.000Z' + is-featured: true + brand-color: '#000000' + category: 62b720ef280c7a7a3be8cabf + author: 62b720ef280c7a7a3be8cab0 + tags: + - 62b720ef280c7a7a3be8cab1 + - 62b720ef280c7a7a3be8cab2 + downloadable-asset: + fileId: 62b720ef280c7a7a3be8cab3 + url: /files/62b720ef280c7a7a3be8cab3_document.pdf response: body: id: 42b720ef280c7a7a3be8cabe @@ -701,14 +869,43 @@ service: isArchived: false isDraft: false fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - color: '#db4b68' - date: '2022-11-18T00:00:00.000Z' - featured: true + name: The Hitchhiker's Guide to the Galaxy + slug: hitchhikers-guide-to-the-galaxy + plain-text: Don't Panic. + rich-text: >- +

A Guide to Interstellar Travel

A towel is about the + most massively useful thing an interstellar hitchhiker can + have. Don't forget yours!

+ main-image: + fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + image-gallery: + - fileId: 62b720ef280c7a7a3be8cabd + url: /files/62b720ef280c7a7a3be8cabd_image.png + - fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + intro-video: https://www.youtube.com/watch?v=aJ83KAggd-4 + official-site: >- + https://hitchhikers.fandom.com/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy + contact-email: zaphod.beeblebrox@heartofgold.gov + support-phone: 424-242-4242 + answer-to-everything: 42 + release-date: '1979-10-12T00:00:00.000Z' + is-featured: true + brand-color: '#000000' + category: 62b720ef280c7a7a3be8cabf + author: 62b720ef280c7a7a3be8cab0 + tags: + - 62b720ef280c7a7a3be8cab1 + - 62b720ef280c7a7a3be8cab2 + downloadable-asset: + fileId: 62b720ef280c7a7a3be8cab3 + url: /files/62b720ef280c7a7a3be8cab3_document.pdf - name: MultipleItems path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 + query-parameters: + skipInvalidFiles: true request: items: - isArchived: false @@ -735,24 +932,51 @@ service: isArchived: false isDraft: false fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - color: '#db4b68' - date: '2022-11-18T00:00:00.000Z' - featured: true + name: The Hitchhiker's Guide to the Galaxy + slug: hitchhikers-guide-to-the-galaxy + plain-text: Don't Panic. + rich-text: >- +

A Guide to Interstellar Travel

A towel is about the + most massively useful thing an interstellar hitchhiker can + have. Don't forget yours!

+ main-image: + fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + image-gallery: + - fileId: 62b720ef280c7a7a3be8cabd + url: /files/62b720ef280c7a7a3be8cabd_image.png + - fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + intro-video: https://www.youtube.com/watch?v=aJ83KAggd-4 + official-site: >- + https://hitchhikers.fandom.com/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy + contact-email: zaphod.beeblebrox@heartofgold.gov + support-phone: 424-242-4242 + answer-to-everything: 42 + release-date: '1979-10-12T00:00:00.000Z' + is-featured: true + brand-color: '#000000' + category: 62b720ef280c7a7a3be8cabf + author: 62b720ef280c7a7a3be8cab0 + tags: + - 62b720ef280c7a7a3be8cab1 + - 62b720ef280c7a7a3be8cab2 + downloadable-asset: + fileId: 62b720ef280c7a7a3be8cab3 + url: /files/62b720ef280c7a7a3be8cab3_document.pdf delete-items-live: path: /collections/{collection_id}/items/live method: DELETE - auth: true + auth: + - OAuth2: + - cms:write docs: > - Remove an item or multiple items (up to 100 items) from the live site. - Deleting published items will unpublish the items from the live site and - set them to draft. + Unpublish up to 100 items from the live site and set the `isDraft` + property to `true`. - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the - items are localized, items will be unpublished only in the primary - locale. + Items will only be unpublished in the + primary locale unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -762,12 +986,12 @@ service: collection_id: type: string docs: Unique identifier for a Collection - display-name: Delete Live Collection Items + display-name: Unpublish Live Collection Items request: name: ItemsDeleteItemsLiveRequest body: properties: - items: optional> + items: list content-type: application/json errors: - root.BadRequestError @@ -778,18 +1002,22 @@ service: examples: - path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 - request: {} + request: + items: + - id: 580e64008c9a982ac9b8b754 update-items-live: path: /collections/{collection_id}/items/live method: PATCH - auth: true + auth: + - OAuth2: + - cms:write docs: > - Update a single live item or multiple live items (up to 100) in a - Collection + Update a single published item or multiple published items (up to 100) + in a Collection - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the - items are localized, items will be updated only in the primary locale. + Items will only be updated in the primary + locale, unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -802,6 +1030,13 @@ service: display-name: Update Live Collection Items request: name: ItemsUpdateItemsLiveRequest + query-parameters: + skipInvalidFiles: + type: optional + default: true + docs: >- + When true, invalid files are skipped and processing continues. + When false, the entire request fails if any file is invalid. body: properties: items: optional> @@ -809,16 +1044,20 @@ service: response: docs: Request was successful type: root.CollectionItemListNoPagination + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError - root.NotFoundError + - root.ConflictError - root.TooManyRequestsError - root.InternalServerError examples: - name: LocalizedItems path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 + query-parameters: + skipInvalidFiles: true request: items: - id: 66f6ed9576ddacf3149d5ea6 @@ -850,44 +1089,44 @@ service: items: - id: 66f6ed9576ddacf3149d5ea6 cmsLocaleId: 66f6e966c9e1dc700a857ca5 - lastPublished: '2023-03-17T18:47:35.560Z' + lastPublished: '2024-09-27T17:38:29.066Z' lastUpdated: '2024-09-27T17:38:29.066Z' createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true + isArchived: false + isDraft: false fieldData: name: Ne Paniquez Pas slug: ne-paniquez-pas featured: false - id: 66f6ed9576ddacf3149d5ea6 cmsLocaleId: 66f6e966c9e1dc700a857ca4 - lastPublished: '2023-03-17T18:47:35.560Z' + lastPublished: '2024-09-27T17:38:29.066Z' lastUpdated: '2024-09-27T17:38:29.066Z' createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true + isArchived: false + isDraft: false fieldData: name: No Entrar en Pánico slug: no-entrar-en-panico featured: false - id: 66f6ed9576ddacf3149d5eaa cmsLocaleId: 66f6e966c9e1dc700a857ca5 - lastPublished: '2023-03-17T18:47:35.560Z' + lastPublished: '2024-09-27T17:38:29.066Z' lastUpdated: '2024-09-27T17:38:29.066Z' createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true + isArchived: false + isDraft: false fieldData: name: Au Revoir et Merci pour Tous les Poissons slug: au-revoir-et-merci featured: false - id: 66f6ed9576ddacf3149d5eaa cmsLocaleId: 66f6e966c9e1dc700a857ca4 - lastPublished: '2023-03-17T18:47:35.560Z' + lastPublished: '2024-09-27T17:38:29.066Z' lastUpdated: '2024-09-27T17:38:29.066Z' createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true + isArchived: false + isDraft: false fieldData: name: Hasta Luego y Gracias por Todo el Pescado slug: hasta-luego-y-gracias @@ -895,6 +1134,8 @@ service: - name: MultipleItems path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 + query-parameters: + skipInvalidFiles: true request: items: - id: 580e64008c9a982ac9b8b754 @@ -918,44 +1159,44 @@ service: items: - id: 66f6ed9576ddacf3149d5ea6 cmsLocaleId: 66f6e966c9e1dc700a857ca5 - lastPublished: '2023-03-17T18:47:35.560Z' + lastPublished: '2024-09-27T17:38:29.066Z' lastUpdated: '2024-09-27T17:38:29.066Z' createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true + isArchived: false + isDraft: false fieldData: name: Ne Paniquez Pas slug: ne-paniquez-pas featured: false - id: 66f6ed9576ddacf3149d5ea6 cmsLocaleId: 66f6e966c9e1dc700a857ca4 - lastPublished: '2023-03-17T18:47:35.560Z' + lastPublished: '2024-09-27T17:38:29.066Z' lastUpdated: '2024-09-27T17:38:29.066Z' createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true + isArchived: false + isDraft: false fieldData: name: No Entrar en Pánico slug: no-entrar-en-panico featured: false - id: 66f6ed9576ddacf3149d5eaa cmsLocaleId: 66f6e966c9e1dc700a857ca5 - lastPublished: '2023-03-17T18:47:35.560Z' + lastPublished: '2024-09-27T17:38:29.066Z' lastUpdated: '2024-09-27T17:38:29.066Z' createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true + isArchived: false + isDraft: false fieldData: name: Au Revoir et Merci pour Tous les Poissons slug: au-revoir-et-merci featured: false - id: 66f6ed9576ddacf3149d5eaa cmsLocaleId: 66f6e966c9e1dc700a857ca4 - lastPublished: '2023-03-17T18:47:35.560Z' + lastPublished: '2024-09-27T17:38:29.066Z' lastUpdated: '2024-09-27T17:38:29.066Z' createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true + isArchived: false + isDraft: false fieldData: name: Hasta Luego y Gracias por Todo el Pescado slug: hasta-luego-y-gracias @@ -963,6 +1204,8 @@ service: - name: Multiple items updated across multiple locales path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 + query-parameters: + skipInvalidFiles: true request: items: - id: 66f6ed9576ddacf3149d5ea6 @@ -994,51 +1237,53 @@ service: items: - id: 66f6ed9576ddacf3149d5ea6 cmsLocaleId: 66f6e966c9e1dc700a857ca5 - lastPublished: '2023-03-17T18:47:35.560Z' + lastPublished: '2024-09-27T17:38:29.066Z' lastUpdated: '2024-09-27T17:38:29.066Z' createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true + isArchived: false + isDraft: false fieldData: name: Ne Paniquez Pas slug: ne-paniquez-pas featured: false - id: 66f6ed9576ddacf3149d5ea6 cmsLocaleId: 66f6e966c9e1dc700a857ca4 - lastPublished: '2023-03-17T18:47:35.560Z' + lastPublished: '2024-09-27T17:38:29.066Z' lastUpdated: '2024-09-27T17:38:29.066Z' createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true + isArchived: false + isDraft: false fieldData: name: No Entrar en Pánico slug: no-entrar-en-panico featured: false - id: 66f6ed9576ddacf3149d5eaa cmsLocaleId: 66f6e966c9e1dc700a857ca5 - lastPublished: '2023-03-17T18:47:35.560Z' + lastPublished: '2024-09-27T17:38:29.066Z' lastUpdated: '2024-09-27T17:38:29.066Z' createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true + isArchived: false + isDraft: false fieldData: name: Au Revoir et Merci pour Tous les Poissons slug: au-revoir-et-merci featured: false - id: 66f6ed9576ddacf3149d5eaa cmsLocaleId: 66f6e966c9e1dc700a857ca4 - lastPublished: '2023-03-17T18:47:35.560Z' + lastPublished: '2024-09-27T17:38:29.066Z' lastUpdated: '2024-09-27T17:38:29.066Z' createdOn: '2024-09-27T17:38:29.066Z' - isArchived: true - isDraft: true + isArchived: false + isDraft: false fieldData: name: Hasta Luego y Gracias por Todo el Pescado slug: hasta-luego-y-gracias featured: false - - name: Mulitple items updated in a single locale + - name: Multiple items updated in a single locale path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 + query-parameters: + skipInvalidFiles: true request: items: - id: 66f6ed9576ddacf3149d5ea6 @@ -1095,15 +1340,19 @@ service: create-items: path: /collections/{collection_id}/items/bulk method: POST - auth: true + auth: + - OAuth2: + - cms:write docs: > Create an item or multiple items in a CMS Collection across multiple corresponding locales. - **Notes:** + - This endpoint can create up to 100 items in a request. - - If the `cmsLocaleIds` parameter is undefined or empty and localization is enabled, items will only be created in the primary locale. + - If the `cmsLocaleIds` parameter is not included in the request, an item will only be created in the primary locale. + + Required scope | `CMS:write` source: @@ -1115,6 +1364,13 @@ service: display-name: Create Collection Items request: name: CreateBulkCollectionItemRequestBody + query-parameters: + skipInvalidFiles: + type: optional + default: true + docs: >- + When true, invalid files are skipped and processing continues. + When false, the entire request fails if any file is invalid. body: properties: cmsLocaleIds: @@ -1129,12 +1385,13 @@ service: isDraft: type: optional docs: Indicates whether the item is in draft state. - default: false + default: true fieldData: CreateBulkCollectionItemRequestBodyFieldData content-type: application/json response: docs: Request was successful type: root.BulkCollectionItem + status-code: 202 errors: - root.BadRequestError - root.UnauthorizedError @@ -1145,6 +1402,8 @@ service: - name: Create a single item across multiple locales path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 + query-parameters: + skipInvalidFiles: true request: cmsLocaleIds: - 66f6e966c9e1dc700a857ca3 @@ -1173,9 +1432,11 @@ service: date: '2022-11-18T00:00:00.000Z' featured: false color: '#db4b68' - - name: Create multiple items across multipel locales + - name: Create multiple items across multiple locales path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 + query-parameters: + skipInvalidFiles: true request: cmsLocaleIds: - 66f6e966c9e1dc700a857ca3 @@ -1208,6 +1469,8 @@ service: - name: Single item created across multiple locales path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 + query-parameters: + skipInvalidFiles: true request: cmsLocaleIds: - 66f6e966c9e1dc700a857ca3 @@ -1239,6 +1502,8 @@ service: - name: Multiple items created across multiple locales path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 + query-parameters: + skipInvalidFiles: true request: cmsLocaleIds: - 66f6e966c9e1dc700a857ca3 @@ -1270,7 +1535,9 @@ service: get-item: path: /collections/{collection_id}/items/{item_id} method: GET - auth: true + auth: + - OAuth2: + - cms:read docs: | Get details of a selected Collection Item. @@ -1298,6 +1565,7 @@ service: response: docs: Request was successful type: root.CollectionItem + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -1308,6 +1576,8 @@ service: - path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 item_id: 580e64008c9a982ac9b8b754 + query-parameters: + cmsLocaleId: cmsLocaleId response: body: id: 42b720ef280c7a7a3be8cabe @@ -1318,19 +1588,46 @@ service: isArchived: false isDraft: false fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - color: '#db4b68' - date: '2022-11-18T00:00:00.000Z' - featured: true + name: The Hitchhiker's Guide to the Galaxy + slug: hitchhikers-guide-to-the-galaxy + plain-text: Don't Panic. + rich-text: >- +

A Guide to Interstellar Travel

A towel is about the + most massively useful thing an interstellar hitchhiker can + have. Don't forget yours!

+ main-image: + fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + image-gallery: + - fileId: 62b720ef280c7a7a3be8cabd + url: /files/62b720ef280c7a7a3be8cabd_image.png + - fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + intro-video: https://www.youtube.com/watch?v=aJ83KAggd-4 + official-site: >- + https://hitchhikers.fandom.com/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy + contact-email: zaphod.beeblebrox@heartofgold.gov + support-phone: 424-242-4242 + answer-to-everything: 42 + release-date: '1979-10-12T00:00:00.000Z' + is-featured: true + brand-color: '#000000' + category: 62b720ef280c7a7a3be8cabf + author: 62b720ef280c7a7a3be8cab0 + tags: + - 62b720ef280c7a7a3be8cab1 + - 62b720ef280c7a7a3be8cab2 + downloadable-asset: + fileId: 62b720ef280c7a7a3be8cab3 + url: /files/62b720ef280c7a7a3be8cab3_document.pdf delete-item: path: /collections/{collection_id}/items/{item_id} method: DELETE - auth: true - docs: > - Delete an Item from a Collection. This endpoint does not currently - support bulk deletion. - + auth: + - OAuth2: + - cms:write + docs: | + Delete an item from a collection. Required scope | `CMS:write` source: @@ -1363,10 +1660,14 @@ service: - path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 item_id: 580e64008c9a982ac9b8b754 + query-parameters: + cmsLocaleId: cmsLocaleId update-item: path: /collections/{collection_id}/items/{item_id} method: PATCH - auth: true + auth: + - OAuth2: + - cms:write docs: | Update a selected Item in a Collection. @@ -1383,10 +1684,19 @@ service: display-name: Update Collection Item request: body: root.CollectionItemPatchSingle + query-parameters: + skipInvalidFiles: + type: optional + default: true + docs: >- + When true, invalid files are skipped and processing continues. + When false, the entire request fails if any file is invalid. + name: ItemsUpdateItemRequest content-type: application/json response: docs: Request was successful type: root.CollectionItem + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -1397,15 +1707,44 @@ service: - path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 item_id: 580e64008c9a982ac9b8b754 + query-parameters: + skipInvalidFiles: true request: isArchived: false isDraft: false fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - date: '2022-11-18T00:00:00.000Z' - featured: true - color: '#db4b68' + name: The Hitchhiker's Guide to the Galaxy + slug: hitchhikers-guide-to-the-galaxy + plain-text: Don't Panic. + rich-text: >- +

A Guide to Interstellar Travel

A towel is about the + most massively useful thing an interstellar hitchhiker can have. + Don't forget yours!

+ main-image: + fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + image-gallery: + - fileId: 62b720ef280c7a7a3be8cabd + url: /files/62b720ef280c7a7a3be8cabd_image.png + - fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + intro-video: https://www.youtube.com/watch?v=aJ83KAggd-4 + official-site: >- + https://hitchhikers.fandom.com/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy + contact-email: zaphod.beeblebrox@heartofgold.gov + support-phone: 424-242-4242 + answer-to-everything: 42 + release-date: '1979-10-12T00:00:00.000Z' + is-featured: true + brand-color: '#000000' + category: 62b720ef280c7a7a3be8cabf + author: 62b720ef280c7a7a3be8cab0 + tags: + - 62b720ef280c7a7a3be8cab1 + - 62b720ef280c7a7a3be8cab2 + downloadable-asset: + fileId: 62b720ef280c7a7a3be8cab3 + url: /files/62b720ef280c7a7a3be8cab3_document.pdf response: body: id: 42b720ef280c7a7a3be8cabe @@ -1416,18 +1755,51 @@ service: isArchived: false isDraft: false fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - color: '#db4b68' - date: '2022-11-18T00:00:00.000Z' - featured: true + name: The Hitchhiker's Guide to the Galaxy + slug: hitchhikers-guide-to-the-galaxy + plain-text: Don't Panic. + rich-text: >- +

A Guide to Interstellar Travel

A towel is about the + most massively useful thing an interstellar hitchhiker can + have. Don't forget yours!

+ main-image: + fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + image-gallery: + - fileId: 62b720ef280c7a7a3be8cabd + url: /files/62b720ef280c7a7a3be8cabd_image.png + - fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + intro-video: https://www.youtube.com/watch?v=aJ83KAggd-4 + official-site: >- + https://hitchhikers.fandom.com/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy + contact-email: zaphod.beeblebrox@heartofgold.gov + support-phone: 424-242-4242 + answer-to-everything: 42 + release-date: '1979-10-12T00:00:00.000Z' + is-featured: true + brand-color: '#000000' + category: 62b720ef280c7a7a3be8cabf + author: 62b720ef280c7a7a3be8cab0 + tags: + - 62b720ef280c7a7a3be8cab1 + - 62b720ef280c7a7a3be8cab2 + downloadable-asset: + fileId: 62b720ef280c7a7a3be8cab3 + url: /files/62b720ef280c7a7a3be8cab3_document.pdf get-item-live: path: /collections/{collection_id}/items/{item_id}/live method: GET - auth: true + auth: + - OAuth2: + - cms:read docs: | Get details of a selected Collection live Item. + + Serving data to applications in real-time? Use the Content Delivery API at `api-cdn.webflow.com` for better performance. The CDN-backed endpoint is optimized for high-volume reads, while the Data API is designed for writes and management operations. + + Required scope | `CMS:read` source: openapi: ../../../openapi/referenced-specs/v2.yml @@ -1452,6 +1824,8 @@ service: response: docs: Request was successful type: root.CollectionItem + status-code: 200 + url: Data API errors: - root.BadRequestError - root.UnauthorizedError @@ -1462,6 +1836,8 @@ service: - path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 item_id: 580e64008c9a982ac9b8b754 + query-parameters: + cmsLocaleId: cmsLocaleId response: body: id: 42b720ef280c7a7a3be8cabe @@ -1472,21 +1848,51 @@ service: isArchived: false isDraft: false fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - color: '#db4b68' - date: '2022-11-18T00:00:00.000Z' - featured: true + name: The Hitchhiker's Guide to the Galaxy + slug: hitchhikers-guide-to-the-galaxy + plain-text: Don't Panic. + rich-text: >- +

A Guide to Interstellar Travel

A towel is about the + most massively useful thing an interstellar hitchhiker can + have. Don't forget yours!

+ main-image: + fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + image-gallery: + - fileId: 62b720ef280c7a7a3be8cabd + url: /files/62b720ef280c7a7a3be8cabd_image.png + - fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + intro-video: https://www.youtube.com/watch?v=aJ83KAggd-4 + official-site: >- + https://hitchhikers.fandom.com/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy + contact-email: zaphod.beeblebrox@heartofgold.gov + support-phone: 424-242-4242 + answer-to-everything: 42 + release-date: '1979-10-12T00:00:00.000Z' + is-featured: true + brand-color: '#000000' + category: 62b720ef280c7a7a3be8cabf + author: 62b720ef280c7a7a3be8cab0 + tags: + - 62b720ef280c7a7a3be8cab1 + - 62b720ef280c7a7a3be8cab2 + downloadable-asset: + fileId: 62b720ef280c7a7a3be8cab3 + url: /files/62b720ef280c7a7a3be8cab3_document.pdf delete-item-live: path: /collections/{collection_id}/items/{item_id}/live method: DELETE - auth: true + auth: + - OAuth2: + - cms:write docs: > - Remove a live item from the site. Removing a published item will - unpublish the item from the live site and set it to draft. + Unpublish a live item from the site and set the `isDraft` property to + `true`. - This endpoint does not currently support bulk deletion. + For bulk unpublishing, please use [this + endpoint.](/data/v2.0.0/reference/cms/collection-items/live-items/delete-items-live) Required scope | `CMS:write` @@ -1499,7 +1905,7 @@ service: item_id: type: string docs: Unique identifier for an Item - display-name: Delete Live Collection Item + display-name: Unpublish Live Collection Item request: name: ItemsDeleteItemLiveRequest query-parameters: @@ -1520,10 +1926,14 @@ service: - path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 item_id: 580e64008c9a982ac9b8b754 + query-parameters: + cmsLocaleId: cmsLocaleId update-item-live: path: /collections/{collection_id}/items/{item_id}/live method: PATCH - auth: true + auth: + - OAuth2: + - cms:write docs: > Update a selected live Item in a Collection. The updates for this Item will be published to the live site. @@ -1542,29 +1952,68 @@ service: display-name: Update Live Collection Item request: body: root.CollectionItemPatchSingle + query-parameters: + skipInvalidFiles: + type: optional + default: true + docs: >- + When true, invalid files are skipped and processing continues. + When false, the entire request fails if any file is invalid. + name: ItemsUpdateItemLiveRequest content-type: application/json response: docs: Request was successful type: root.CollectionItem + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError - root.NotFoundError + - root.ConflictError - root.TooManyRequestsError - root.InternalServerError examples: - path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 item_id: 580e64008c9a982ac9b8b754 + query-parameters: + skipInvalidFiles: true request: isArchived: false isDraft: false fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - date: '2022-11-18T00:00:00.000Z' - featured: true - color: '#db4b68' + name: The Hitchhiker's Guide to the Galaxy + slug: hitchhikers-guide-to-the-galaxy + plain-text: Don't Panic. + rich-text: >- +

A Guide to Interstellar Travel

A towel is about the + most massively useful thing an interstellar hitchhiker can have. + Don't forget yours!

+ main-image: + fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + image-gallery: + - fileId: 62b720ef280c7a7a3be8cabd + url: /files/62b720ef280c7a7a3be8cabd_image.png + - fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + intro-video: https://www.youtube.com/watch?v=aJ83KAggd-4 + official-site: >- + https://hitchhikers.fandom.com/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy + contact-email: zaphod.beeblebrox@heartofgold.gov + support-phone: 424-242-4242 + answer-to-everything: 42 + release-date: '1979-10-12T00:00:00.000Z' + is-featured: true + brand-color: '#000000' + category: 62b720ef280c7a7a3be8cabf + author: 62b720ef280c7a7a3be8cab0 + tags: + - 62b720ef280c7a7a3be8cab1 + - 62b720ef280c7a7a3be8cab2 + downloadable-asset: + fileId: 62b720ef280c7a7a3be8cab3 + url: /files/62b720ef280c7a7a3be8cab3_document.pdf response: body: id: 42b720ef280c7a7a3be8cabe @@ -1575,15 +2024,44 @@ service: isArchived: false isDraft: false fieldData: - name: Pan Galactic Gargle Blaster Recipe - slug: pan-galactic-gargle-blaster - color: '#db4b68' - date: '2022-11-18T00:00:00.000Z' - featured: true + name: The Hitchhiker's Guide to the Galaxy + slug: hitchhikers-guide-to-the-galaxy + plain-text: Don't Panic. + rich-text: >- +

A Guide to Interstellar Travel

A towel is about the + most massively useful thing an interstellar hitchhiker can + have. Don't forget yours!

+ main-image: + fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + image-gallery: + - fileId: 62b720ef280c7a7a3be8cabd + url: /files/62b720ef280c7a7a3be8cabd_image.png + - fileId: 62b720ef280c7a7a3be8cabe + url: /files/62b720ef280c7a7a3be8cabe_image.png + intro-video: https://www.youtube.com/watch?v=aJ83KAggd-4 + official-site: >- + https://hitchhikers.fandom.com/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy + contact-email: zaphod.beeblebrox@heartofgold.gov + support-phone: 424-242-4242 + answer-to-everything: 42 + release-date: '1979-10-12T00:00:00.000Z' + is-featured: true + brand-color: '#000000' + category: 62b720ef280c7a7a3be8cabf + author: 62b720ef280c7a7a3be8cab0 + tags: + - 62b720ef280c7a7a3be8cab1 + - 62b720ef280c7a7a3be8cab2 + downloadable-asset: + fileId: 62b720ef280c7a7a3be8cab3 + url: /files/62b720ef280c7a7a3be8cab3_document.pdf publish-item: path: /collections/{collection_id}/items/publish method: POST - auth: true + auth: + - OAuth2: + - cms:write docs: | Publish an item or multiple items. @@ -1596,14 +2074,12 @@ service: docs: Unique identifier for a Collection display-name: Publish Collection Item request: - name: ItemsPublishItemRequest - body: - properties: - itemIds: list + body: ItemsPublishItemRequest content-type: application/json response: docs: Request was successful type: ItemsPublishItemResponse + status-code: 202 errors: - root.BadRequestError - root.UnauthorizedError @@ -1612,11 +2088,52 @@ service: - root.TooManyRequestsError - root.InternalServerError examples: - - path-parameters: + - name: PrimaryLocale + path-parameters: collection_id: 580e63fc8c9a982ac9b8b745 request: itemIds: - - itemIds + - 643fd856d66b6528195ee2ca + - 643fd856d66b6528195ee2cb + - 643fd856d66b6528195ee2cc + response: + body: + publishedItemIds: + - 643fd856d66b6528195ee2ca + - 643fd856d66b6528195ee2cb + errors: + - Staging item ID 643fd856d66b6528195ee2cf not found. + - name: SecondaryLocale + path-parameters: + collection_id: 580e63fc8c9a982ac9b8b745 + request: + items: + - id: 643fd856d66b6528195ee2ca + cmsLocaleIds: + - 653ad57de882f528b32e810e + - id: 643fd856d66b6528195ee2cb + cmsLocaleIds: + - 653ad57de882f528b32e810e + - id: 643fd856d66b6528195ee2cc + cmsLocaleIds: + - 653ad57de882f528b32e810e + response: + body: + publishedItemIds: + - 643fd856d66b6528195ee2ca + - 643fd856d66b6528195ee2cb + errors: + - Staging item ID 643fd856d66b6528195ee2cf not found. + - name: MultipleLocales + path-parameters: + collection_id: 580e63fc8c9a982ac9b8b745 + request: + items: + - id: 643fd856d66b6528195ee2ca + cmsLocaleIds: + - 653ad57de882f528b32e810e + - 6514390aea353fc691d69827 + - 65143930ea353fc691d69cd8 response: body: publishedItemIds: diff --git a/.mock/definition/comments.yml b/.mock/definition/comments.yml new file mode 100644 index 0000000..573e375 --- /dev/null +++ b/.mock/definition/comments.yml @@ -0,0 +1,41 @@ +imports: + root: __package__.yml +webhooks: + comment_created: + audiences: [] + method: POST + display-name: New Comment Thread + headers: {} + payload: root.Comment + examples: + - payload: + triggerType: comment_created + payload: + threadId: 679d2ddb5196117ad04d1ffa + commentId: 679d2ddb5196117ad04d1ff8 + type: new_comment + siteId: 679826b3b20b045e176bc4b5 + pageId: 679826b3b20b045e176bc4bc + localeId: 67993753d910db250db64b3e + itemId: 580e64008c9a982ac9b8b754 + breakpoint: main + url: >- + https://webflow.com/design/site-slug-4ec832?workflow=comment&commentId=679d2ddb5196117ad04d1ffa&pageId=679826b3b20b045e176bc4bc + content: 'This comment mentions another user [[6287ec36a841b25637c663df]] ' + isResolved: false + author: + userId: 6287ec36a841b25637c663df + email: ford.prefect@heartofgold.spaceship + name: Ford Prefect + mentionedUsers: + - userId: 6287ec36a841b25637c663df + email: arthur.dent@heartofgold.spaceship + name: Arthur Dent + createdOn: '2025-01-31T20:08:59.759Z' + lastUpdated: '2025-01-31T20:08:59.759Z' + docs: | + Information about a new comment thread or reply + + + There may be a delay of up to 5 minutes before new comments appear in the system and trigger the webhook notification. + diff --git a/.mock/definition/components.yml b/.mock/definition/components.yml index b9eb7d6..3370a4f 100644 --- a/.mock/definition/components.yml +++ b/.mock/definition/components.yml @@ -7,7 +7,9 @@ service: list: path: /sites/{site_id}/components method: GET - auth: true + auth: + - OAuth2: + - components:read docs: | List of all components for a site. @@ -22,17 +24,21 @@ service: request: name: ComponentsListRequest query-parameters: + branchId: + type: optional + docs: Scope the operation to work on a specific branch. limit: - type: optional + type: optional docs: 'Maximum number of records to be returned (max limit: 100)' offset: - type: optional + type: optional docs: >- Offset used for pagination if the results have more than limit records response: docs: Request was successful type: root.ComponentList + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -42,6 +48,10 @@ service: examples: - path-parameters: site_id: 580e63e98c9a982ac9b8b741 + query-parameters: + branchId: 68026fa68ef6dc744c75b833 + limit: 1 + offset: 1 response: body: components: @@ -74,10 +84,13 @@ service: get-content: path: /sites/{site_id}/components/{component_id}/dom method: GET - auth: true + auth: + - OAuth2: + - components:read docs: > Get static content from a component definition. This includes text - nodes, image nodes and nested component instances. + nodes, image nodes, select nodes, text input nodes, submit button nodes, + and nested component instances. To retrieve dynamic content set by component properties, use the [get component @@ -106,20 +119,27 @@ service: query-parameters: localeId: type: optional - docs: >- - Unique identifier for a specific locale. Applicable, when using - localization. + docs: > + Unique identifier for a specific Locale. + + + [Lear more about + localization.](/data/v2.0.0/docs/working-with-localization) + branchId: + type: optional + docs: Scope the operation to work on a specific branch. limit: - type: optional + type: optional docs: 'Maximum number of records to be returned (max limit: 100)' offset: - type: optional + type: optional docs: >- Offset used for pagination if the results have more than limit records response: docs: Request was successful type: root.ComponentDom + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -127,80 +147,66 @@ service: - root.TooManyRequestsError - root.InternalServerError examples: - - name: ComponentDOM - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - component_id: 8505ba55-ef72-629e-f85c-33e4b703d48b - query-parameters: - localeId: 65427cf400e02b306eaa04a0 - response: - body: - componentId: 69118560-d0bc-15fc-bbf8-b8fe5f6535b5 - nodes: - - type: component-instance - id: a245c12d-995b-55ee-5ec7-aa36a6cad623 - componentId: nodes - propertyOverrides: - - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 - - type: component-instance - id: a245c12d-995b-55ee-5ec7-aa36a6cad627 - componentId: nodes - propertyOverrides: - - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 - - type: component-instance - id: a245c12d-995b-55ee-5ec7-aa36a6cad629 - componentId: nodes - propertyOverrides: - - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 - - type: component-instance - id: a245c12d-995b-55ee-5ec7-aa36a6cad631 - componentId: 6258612d1ee792848f805dcf - propertyOverrides: - - propertyId: a245c12d-995b-55ee-5ec7-aa36a6cad633 - type: Plain Text - text: - text: Don't Panic! - - propertyId: a245c12d-995b-55ee-5ec7-aa36a6cad635 - type: Rich Text - text: - html:

Always know where your towel is.

- pagination: - limit: 4 - offset: 0 - total: 4 - - name: LocalizedComponentDOM - path-parameters: + - path-parameters: site_id: 580e63e98c9a982ac9b8b741 component_id: 8505ba55-ef72-629e-f85c-33e4b703d48b query-parameters: localeId: 65427cf400e02b306eaa04a0 + branchId: 68026fa68ef6dc744c75b833 + limit: 1 + offset: 1 response: body: componentId: 69118560-d0bc-15fc-bbf8-b8fe5f6535b5 nodes: - - type: component-instance - id: 69118560-d0bc-15fc-bbf8-b8fe5f6535b8 - componentId: nodes + - id: id + text: {} + attributes: + key: value + type: text + - id: id + text: {} + attributes: + key: value + type: text + - id: id + image: {} + attributes: + key: value + type: image + - id: id + placeholder: placeholder + attributes: + key: value + type: text-input + - id: id + choices: + - value: value + text: text + attributes: + key: value + type: select + - id: id + value: value + waitingText: waitingText + attributes: + key: value + type: submit-button + - id: id + componentId: componentId propertyOverrides: - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 - - type: component-instance - id: 8ebfb409-7493-3bca-5d48-0e547befb960 - componentId: nodes - propertyOverrides: - - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 - - type: component-instance - id: 69118560-d0bc-15fc-bbf8-b8fe5f6535c2 - componentId: 69118560-d0bc-15fc-bbf8-b8fe5f6535b5 - propertyOverrides: - - propertyId: a245c12d-995b-55ee-5ec7-aa36a6cad623 + type: component-instance pagination: - limit: 100 + limit: 7 offset: 0 - total: 3 + total: 7 update-content: path: /sites/{site_id}/components/{component_id}/dom method: POST - auth: true + auth: + - OAuth2: + - components:write docs: > This endpoint updates content within a component defintion for **secondary locales**. It supports updating up to 1000 nodes in a single @@ -211,13 +217,18 @@ service: 1. Use the [get component content](/data/reference/pages-and-components/components/get-content) - endpoint to identify available content nodes and their types + endpoint to identify available content nodes and their types. 2. If your component definition has a component instance nested within it, retrieve the nested component instance's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) - endpoint + endpoint. + + 3. DOM elements may include a `data-w-id` attribute. This attribute is + used by Webflow to maintain custom attributes and links across locales. + Always include the original `data-w-id` value in your update requests to + ensure consistent behavior across all locales. @@ -241,9 +252,15 @@ service: query-parameters: localeId: type: optional - docs: >- - Unique identifier for a specific locale. Applicable, when using - localization. + docs: > + Unique identifier for a specific Locale. + + + [Lear more about + localization.](/data/v2.0.0/docs/working-with-localization) + branchId: + type: optional + docs: Scope the operation to work on a specific branch. body: properties: nodes: @@ -255,6 +272,7 @@ service: response: docs: Request was successful type: ComponentsUpdateContentResponse + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -268,6 +286,7 @@ service: component_id: 8505ba55-ef72-629e-f85c-33e4b703d48b query-parameters: localeId: 65427cf400e02b306eaa04a0 + branchId: 68026fa68ef6dc744c75b833 request: nodes: - nodeId: a245c12d-995b-55ee-5ec7-aa36a6cad623 @@ -276,6 +295,17 @@ service: text: >-

Don't Panic!

Always know where your towel is.

+ - nodeId: a245c12d-995b-55ee-5ec7-aa36a6cad635 + choices: + - value: choice-1 + text: First choice + - value: choice-2 + text: Second choice + - nodeId: a245c12d-995b-55ee-5ec7-aa36a6cad642 + placeholder: Enter something here... + - nodeId: a245c12d-995b-55ee-5ec7-aa36a6cad671 + value: Submit + waitingText: Submitting... - nodeId: a245c12d-995b-55ee-5ec7-aa36a6cad629 propertyOverrides: - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 @@ -289,12 +319,14 @@ service: get-properties: path: /sites/{site_id}/components/{component_id}/properties method: GET - auth: true + auth: + - OAuth2: + - components:read docs: > - Get the property default values of a component definition. + Get the default property values of a component definition. - If you do not provide a Locale ID in your request, the response + If you do not include a `localeId` in your request, the response will return any properties that can be localized from the Primary locale. @@ -315,20 +347,27 @@ service: query-parameters: localeId: type: optional - docs: >- - Unique identifier for a specific locale. Applicable, when using - localization. + docs: > + Unique identifier for a specific Locale. + + + [Lear more about + localization.](/data/v2.0.0/docs/working-with-localization) + branchId: + type: optional + docs: Scope the operation to work on a specific branch. limit: - type: optional + type: optional docs: 'Maximum number of records to be returned (max limit: 100)' offset: - type: optional + type: optional docs: >- Offset used for pagination if the results have more than limit records response: docs: Request was successful type: root.ComponentProperties + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -341,6 +380,9 @@ service: component_id: 8505ba55-ef72-629e-f85c-33e4b703d48b query-parameters: localeId: 65427cf400e02b306eaa04a0 + branchId: 68026fa68ef6dc744c75b833 + limit: 1 + offset: 1 response: body: componentId: 658205daa3e8206a523b5ad4 @@ -364,9 +406,11 @@ service: update-properties: path: /sites/{site_id}/components/{component_id}/properties method: POST - auth: true + auth: + - OAuth2: + - components:write docs: > - Update the property default values of a component definition in a + Update the default property values of a component definition in a specificed locale. @@ -374,10 +418,16 @@ service: 1. Use the [get component properties](/data/reference/pages-and-components/components/get-properties) - endpoint to identify available properties + endpoint to identify properties that can be updated in a secondary + locale. + 2. Rich Text properties may include a `data-w-id` attribute. This + attribute is used by Webflow to maintain links across locales. Always + include the original `data-w-id` value in your update requests to ensure + consistent behavior across all locales. - The request requires a secondary locale ID. If a locale is + + The request requires a secondary locale ID. If a `localeId` is missing, the request will not be processed and will result in an error. @@ -398,9 +448,15 @@ service: query-parameters: localeId: type: optional - docs: >- - Unique identifier for a specific locale. Applicable, when using - localization. + docs: > + Unique identifier for a specific Locale. + + + [Lear more about + localization.](/data/v2.0.0/docs/working-with-localization) + branchId: + type: optional + docs: Scope the operation to work on a specific branch. body: properties: properties: @@ -412,6 +468,7 @@ service: response: docs: Request was successful type: ComponentsUpdatePropertiesResponse + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -424,6 +481,7 @@ service: component_id: 8505ba55-ef72-629e-f85c-33e4b703d48b query-parameters: localeId: 65427cf400e02b306eaa04a0 + branchId: 68026fa68ef6dc744c75b833 request: properties: - propertyId: a245c12d-995b-55ee-5ec7-aa36a6cad623 @@ -442,8 +500,12 @@ types: ComponentDomWriteNodesItem: discriminated: false union: - - root.TextNodeWrite - - root.ComponentInstanceNodePropertyOverridesWrite + - type: root.TextNodeWrite + - type: root.ComponentInstanceNodePropertyOverridesWrite + - type: root.Select + - type: root.TextInputNodeWrite + - type: root.SubmitButtonNodeWrite + - type: root.SearchButtonNodeWrite source: openapi: ../../../openapi/referenced-specs/v2.yml inline: true diff --git a/.mock/definition/ecommerce.yml b/.mock/definition/ecommerce.yml index 1a2ca95..426869f 100644 --- a/.mock/definition/ecommerce.yml +++ b/.mock/definition/ecommerce.yml @@ -7,7 +7,9 @@ service: get-settings: path: /sites/{site_id}/ecommerce/settings method: GET - auth: true + auth: + - OAuth2: + - ecommerce:read docs: | Retrieve ecommerce settings for a site. @@ -22,6 +24,7 @@ service: response: docs: Request was successful type: root.EcommerceSettings + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError diff --git a/.mock/definition/forms.yml b/.mock/definition/forms.yml index 9eac177..08f2926 100644 --- a/.mock/definition/forms.yml +++ b/.mock/definition/forms.yml @@ -7,7 +7,9 @@ service: list: path: /sites/{site_id}/forms method: GET - auth: true + auth: + - OAuth2: + - forms:read docs: | List forms for a given site. @@ -23,16 +25,17 @@ service: name: FormsListRequest query-parameters: limit: - type: optional + type: optional docs: 'Maximum number of records to be returned (max limit: 100)' offset: - type: optional + type: optional docs: >- Offset used for pagination if the results have more than limit records response: docs: Request was successful type: root.FormList + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -44,6 +47,9 @@ service: examples: - path-parameters: site_id: 580e63e98c9a982ac9b8b741 + query-parameters: + limit: 1 + offset: 1 response: body: forms: @@ -53,13 +59,16 @@ service: fields: '0': displayName: Email + placeholder: Enter your email userVisible: true '1': displayName: Email + placeholder: Enter your email userVisible: true responseSettings: redirectUrl: https://example.com redirectMethod: GET + redirectAction: POST https://example.com sendEmailConfirmation: true id: 589a331aa51e760df7ccb89e siteId: 580e63e98c9a982ac9b8b741 @@ -74,10 +83,12 @@ service: fields: '0': displayName: Email + placeholder: Enter your email userVisible: true responseSettings: redirectUrl: https://example.com redirectMethod: GET + redirectAction: POST https://example.com sendEmailConfirmation: false id: 580ff8d7ba3e45ba9fe588e9 siteId: 580e63e98c9a982ac9b8b741 @@ -93,7 +104,9 @@ service: get: path: /forms/{form_id} method: GET - auth: true + auth: + - OAuth2: + - forms:read docs: | Get information about a given form. @@ -108,6 +121,7 @@ service: response: docs: Request was successful type: root.Form + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -149,10 +163,18 @@ service: list-submissions: path: /forms/{form_id}/submissions method: GET - auth: true + auth: + - OAuth2: + - forms:read docs: | List form submissions for a given form + + When a form is used in a component definition, each instance of the form is considered a unique form. + + To get a combined list of submissions for a form that appears across multiple component instances, use the [List Form Submissions by Site](/data/reference/forms/form-submissions/list-submissions-by-site) endpoint. + + Required scope | `forms:read` source: openapi: ../../../openapi/referenced-specs/v2.yml @@ -165,16 +187,17 @@ service: name: FormsListSubmissionsRequest query-parameters: offset: - type: optional + type: optional docs: >- Offset used for pagination if the results have more than limit records limit: - type: optional + type: optional docs: 'Maximum number of records to be returned (max limit: 100)' response: docs: Request was successful type: root.FormSubmissionList + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -185,6 +208,9 @@ service: examples: - path-parameters: form_id: 580e63e98c9a982ac9b8b741 + query-parameters: + offset: 1 + limit: 1 response: body: formSubmissions: @@ -211,7 +237,9 @@ service: get-submission: path: /form_submissions/{form_submission_id} method: GET - auth: true + auth: + - OAuth2: + - forms:read docs: | Get information about a given form submissio. @@ -226,6 +254,7 @@ service: response: docs: Request was successful type: root.FormSubmission + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -246,10 +275,41 @@ service: formResponse: First Name: Arthur Last Name: Dent + delete-submission: + path: /form_submissions/{form_submission_id} + method: DELETE + auth: + - OAuth2: + - forms:write + docs: | + Delete a form submission + + + Required scope | `forms:write` + source: + openapi: ../../../openapi/referenced-specs/v2.yml + path-parameters: + form_submission_id: + type: string + docs: Unique identifier for a Form Submission + display-name: Delete Form Submission + errors: + - root.BadRequestError + - root.UnauthorizedError + - root.ForbiddenError + - root.NotFoundError + - root.ConflictError + - root.TooManyRequestsError + - root.InternalServerError + examples: + - path-parameters: + form_submission_id: 580e63e98c9a982ac9b8b741 update-submission: path: /form_submissions/{form_submission_id} method: PATCH - auth: true + auth: + - OAuth2: + - forms:write docs: | Update hidden fields on a form submission @@ -274,6 +334,7 @@ service: response: docs: Request was successful type: root.FormSubmission + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -300,3 +361,39 @@ service: openapi: ../../../openapi/referenced-specs/v2.yml display-name: Forms docs: Forms are forms that are created on your Webflow site. +webhooks: + form_submission: + audiences: [] + method: POST + display-name: Form Submission + headers: {} + payload: root.FormSubmissionTrigger + examples: + - payload: + triggerType: form_submission + payload: + name: Contact Us + siteId: 65427cf400e02b306eaa049c + data: + First Name: Zaphod + Last Name: Beeblebrox + email: zaphod@heartofgold.ai + Phone Number: 15550000000 + schema: + - fieldName: First Name + fieldType: FormTextInput + fieldElementId: 285042f7-d554-dc7f-102c-aa10d6a2d2c4 + - fieldName: Last Name + fieldType: FormTextInput + fieldElementId: 285042f7-d554-dc7f-102c-aa10d6a2d2c5 + - fieldName: email + fieldType: FormTextInput + fieldElementId: 285042f7-d554-dc7f-102c-aa10d6a2d2c6 + - fieldName: Phone Number + fieldType: FormTextInput + fieldElementId: 285042f7-d554-dc7f-102c-aa10d6a2d2c7 + submittedAt: '2022-09-14T12:35:16.117Z' + id: 6321ca84df3949bfc6752327 + formId: 65429eadebe8a9f3a30f62d0 + formElementId: 4e038d2c-6a1e-4953-7be9-a59a2b453177 + docs: Information about a form that was subitted diff --git a/.mock/definition/inventory.yml b/.mock/definition/inventory.yml index 5e69c29..139fa04 100644 --- a/.mock/definition/inventory.yml +++ b/.mock/definition/inventory.yml @@ -5,9 +5,11 @@ service: base-path: '' endpoints: list: - path: /collections/{collection_id}/items/{item_id}/inventory + path: /collections/{sku_collection_id}/items/{sku_id}/inventory method: GET - auth: true + auth: + - OAuth2: + - ecommerce:read docs: | List the current inventory levels for a particular SKU item. @@ -15,16 +17,19 @@ service: source: openapi: ../../../openapi/referenced-specs/v2.yml path-parameters: - collection_id: + sku_collection_id: type: string - docs: Unique identifier for a Collection - item_id: + docs: >- + Unique identifier for a SKU collection. Use the List Collections API + to find this ID. + sku_id: type: string - docs: Unique identifier for an Item + docs: Unique identifier for a SKU display-name: List Inventory response: docs: Request was successful type: root.InventoryItem + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -35,17 +40,19 @@ service: - root.InternalServerError examples: - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - item_id: 580e64008c9a982ac9b8b754 + sku_collection_id: 6377a7c4b7a79608c34a46f7 + sku_id: 5e8518516e147040726cc415 response: body: id: 5bfedb42bab0ad90fa7dad39 quantity: 100 inventoryType: finite update: - path: /collections/{collection_id}/items/{item_id}/inventory + path: /collections/{sku_collection_id}/items/{sku_id}/inventory method: PATCH - auth: true + auth: + - OAuth2: + - ecommerce:write docs: > Updates the current inventory levels for a particular SKU item. @@ -64,12 +71,14 @@ service: source: openapi: ../../../openapi/referenced-specs/v2.yml path-parameters: - collection_id: + sku_collection_id: type: string - docs: Unique identifier for a Collection - item_id: + docs: >- + Unique identifier for a SKU collection. Use the List Collections API + to find this ID. + sku_id: type: string - docs: Unique identifier for an Item + docs: Unique identifier for a SKU display-name: Update Item Inventory request: name: InventoryUpdateRequest @@ -88,6 +97,7 @@ service: response: docs: Request was successful type: root.InventoryItem + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -98,8 +108,8 @@ service: - root.InternalServerError examples: - path-parameters: - collection_id: 580e63fc8c9a982ac9b8b745 - item_id: 580e64008c9a982ac9b8b754 + sku_collection_id: 6377a7c4b7a79608c34a46f7 + sku_id: 5e8518516e147040726cc415 request: inventoryType: infinite response: @@ -120,3 +130,23 @@ types: inline: true source: openapi: ../../../openapi/referenced-specs/v2.yml + EcommInventoryChangedPayload: + properties: + triggerType: optional> + payload: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml +webhooks: + ecomm_inventory_changed: + audiences: [] + method: POST + display-name: Updated eComm Inventory + headers: {} + payload: EcommInventoryChangedPayload + examples: + - name: WebhookInventoryChanged + payload: + triggerType: ecomm_inventory_changed + payload: + \$ref: ./schemas/inventory.yml#/InventoryItem/example + docs: Information about updated ecommerce inventory values diff --git a/.mock/definition/items.yml b/.mock/definition/items.yml new file mode 100644 index 0000000..634f1f7 --- /dev/null +++ b/.mock/definition/items.yml @@ -0,0 +1,112 @@ +imports: + root: __package__.yml +webhooks: + collection_item_created: + audiences: [] + method: POST + display-name: Collection Item Created + headers: {} + payload: root.CollectionItemCreated + examples: + - payload: + triggerType: collection_item_created + payload: + id: 580e64008c9a982ac9b8b754 + workspaceId: 625860a7a6c16d624927122f + siteId: 65427cf400e02b306eaa049c + collectionId: 664243617fcc8b464b23c4ee + lastPublished: '2023-03-17T18:47:35Z' + lastUpdated: '2023-03-17T18:47:35Z' + createdOn: '2023-03-17T18:47:35Z' + isArchived: false + isDraft: false + fieldData: + name: Pan-Galactic Gargle Blaster + slug: pan-galactic-gargle-blaster + docs: Information about a new collection item + collection_item_changed: + audiences: [] + method: POST + display-name: Collection Item Updated + headers: {} + payload: root.CollectionItemChanged + examples: + - payload: + triggerType: collection_item_changed + payload: + id: id + workspaceId: workspaceId + siteId: siteId + collectionId: collectionId + fieldData: + name: name + slug: slug + docs: Information about an updated collection item + collection_item_deleted: + audiences: [] + method: POST + display-name: Collection Item Deleted + headers: {} + payload: root.CollectionItemRemoved + examples: + - payload: + triggerType: collection_item_deleted + payload: + id: 66424365e972c886137a1cf1 + siteId: 65427cf400e02b306eaa049c + workspaceId: 625860a7a6c16d624927122f + collectionId: 664243617fcc8b464b23c4ee + cmsLocaleId: 681442a144bb80bd00480fda + lastUpdated: '2025-05-28T04:44:33Z' + createdOn: '2025-05-28T04:27:12Z' + isArchived: false + isDraft: false + fieldData: + name: Earth + slug: earth + description: Mostly harmless + color: '#0000FF' + type: planet + galaxy: Milky Way + docs: Information about a deleted collection item + collection_item_published: + audiences: [] + method: POST + display-name: Collection Item Published + headers: {} + payload: root.CollectionItemPublished + examples: + - payload: + triggerType: collection_item_published + payload: + id: 6321ca84df3949bfc6752327 + siteId: 65427cf400e02b306eaa049c + workspaceId: 625860a7a6c16d624927122f + collectionId: 664243617fcc8b464b23c4ee + cmsLocaleId: 681442a144bb80bd00480fda + docs: Information about a collection item that was published + collection_item_unpublished: + audiences: [] + method: POST + display-name: Collection Item Unpublished + headers: {} + payload: root.CollectionItemUnpublished + examples: + - payload: + triggerType: collection_item_unpublished + payload: + id: 66424365e972c886137a1cf1 + siteId: 65427cf400e02b306eaa049c + workspaceId: 625860a7a6c16d624927122f + collectionId: 664243617fcc8b464b23c4ee + cmsLocaleId: 681442a144bb80bd00480fda + lastUpdated: '2025-05-28T04:44:33Z' + createdOn: '2025-05-28T04:27:12Z' + isArchived: false + isDraft: false + fieldData: + name: Anna Gunn + slug: anna-gunn + _locale: 681442a144bb80bd00480fda + _noSearch: false + docs: Information about a collection item that was removed from the live site diff --git a/.mock/definition/orders.yml b/.mock/definition/orders.yml index b2802cf..1f9711e 100644 --- a/.mock/definition/orders.yml +++ b/.mock/definition/orders.yml @@ -28,7 +28,9 @@ service: list: path: /sites/{site_id}/orders method: GET - auth: true + auth: + - OAuth2: + - ecommerce:read docs: | List all orders created for a given site. @@ -47,16 +49,17 @@ service: type: optional docs: Filter the orders by status offset: - type: optional + type: optional docs: >- Offset used for pagination if the results have more than limit records limit: - type: optional + type: optional docs: 'Maximum number of records to be returned (max limit: 100)' response: docs: Request was successful type: root.OrderList + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -68,6 +71,10 @@ service: examples: - path-parameters: site_id: 580e63e98c9a982ac9b8b741 + query-parameters: + status: pending + offset: 1 + limit: 1 response: body: orders: @@ -89,15 +96,15 @@ service: customerPaid: unit: USD value: '5892' - string: ' 211.55 USD' + string: \$ 211.55 USD netAmount: unit: USD value: '5892' - string: ' 200.89 USD' + string: \$ 200.89 USD applicationFee: unit: USD value: '5892' - string: ' 4.23 USD' + string: \$ 4.23 USD allAddresses: - type: billing addressee: Arthur Dent @@ -145,7 +152,7 @@ service: rowTotal: unit: USD value: '5892' - string: ' 111.22 USD' + string: \$ 111.22 USD productId: 66072fb61b89448912e26791 productName: Luxurious Fresh Ball productSlug: luxurious-fresh-ball @@ -155,11 +162,11 @@ service: variantSKU: luxurious-fresh-ball-generic-bronze-practical-plastic variantImage: url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg + https://dev-assets.website-files.com/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg variantPrice: unit: USD value: '5892' - string: ' 55.61 USD' + string: \$ 55.61 USD weight: 11 width: 82 height: 70 @@ -168,7 +175,7 @@ service: rowTotal: unit: USD value: '5892' - string: ' 83.09 USD' + string: \$ 83.09 USD productId: 66072fb61b89448912e2678b productName: Incredible Bronze Towels productSlug: incredible-bronze-towels @@ -180,20 +187,23 @@ service: variantSKU: incredible-bronze-towels-sleek-frozen-incredible-metal variantImage: url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e26729_image16.jpeg + https://dev-assets.website-files.com/66072f39417a2a35b2589cc7/66072fb51b89448912e26729_image16.jpeg variantPrice: unit: USD value: '5892' - string: ' 83.09 USD' + string: \$ 83.09 USD + weight: 5 width: 19 height: 72 length: 18 purchasedItemsCount: 3 stripeDetails: + subscriptionId: sub_1J6xwG2eZvKYlo2CXu9Zt0Tn paymentMethod: pm_1P410gJYFi4lcbXWbeKghqjK paymentIntentId: pi_3P410iJYFi4lcbXW0EKKgcVg customerId: cus_Ptod8KJBiiPgnH chargeId: ch_3P410iJYFi4lcbXW0DxUkzCH + refundReason: requested_by_customer stripeCard: last4: '4242' brand: Visa @@ -224,7 +234,7 @@ service: price: unit: USD value: '5892' - string: '3.44' + string: \$3.44 downloadFiles: - id: 5e9a5eba75e0ac242e1b6f64 name: The modern web design process - Webflow Ebook.pdf @@ -243,15 +253,15 @@ service: customerPaid: unit: USD value: '5892' - string: ' 118.73 USD' + string: \$ 118.73 USD netAmount: unit: USD value: '5892' - string: ' 112.62 USD' + string: \$ 112.62 USD applicationFee: unit: USD value: '5892' - string: ' 2.37 USD' + string: \$ 2.37 USD allAddresses: - type: billing addressee: Arthur Dent @@ -298,7 +308,7 @@ service: rowTotal: unit: USD value: '5892' - string: ' 55.61 USD' + string: \$ 55.61 USD productId: 66072fb61b89448912e26791 productName: Luxurious Fresh Ball productSlug: luxurious-fresh-ball @@ -308,11 +318,11 @@ service: variantSKU: luxurious-fresh-ball-generic-bronze-practical-plastic variantImage: url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg + https://dev-assets.website-files.com/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg variantPrice: unit: USD value: '5892' - string: ' 55.61 USD' + string: \$ 55.61 USD weight: 11 width: 82 height: 70 @@ -321,7 +331,7 @@ service: rowTotal: unit: USD value: '5892' - string: ' 53.44 USD' + string: \$ 53.44 USD productId: 66072fb61b89448912e26799 productName: Recycled Steel Gloves productSlug: recycled-steel-gloves @@ -335,17 +345,18 @@ service: recycled-steel-gloves-electronic-granite-handcrafted-grey variantImage: url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg + https://dev-assets.website-files.com/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg variantPrice: unit: USD value: '5892' - string: ' 53.44 USD' + string: \$ 53.44 USD weight: 38 width: 76 height: 85 length: 40 purchasedItemsCount: 2 stripeDetails: + subscriptionId: sub_1J6xwG2eZvKYlo2CXu9Zt0Tn paymentMethod: pm_1OzmzBJYFi4lcbXWHKNdXU7j paymentIntentId: pi_3OzmzDJYFi4lcbXW1hTBW6ft customerId: cus_PpRsNHwWdUoRKR @@ -378,7 +389,7 @@ service: subtotal: unit: USD value: '5892' - string: ' 109.05 USD' + string: \$ 109.05 USD extras: - type: tax name: State Taxes @@ -386,25 +397,25 @@ service: price: unit: USD value: '5892' - string: ' 4.36 USD' + string: \$ 4.36 USD - type: tax name: City Taxes description: NEW YORK Taxes (4.88%) price: unit: USD value: '5892' - string: ' 5.32 USD' + string: \$ 5.32 USD - type: shipping name: Flat description: '' price: unit: USD value: '5892' - string: ' 0.00 USD' + string: \$ 0.00 USD total: unit: USD value: '5892' - string: ' 118.73 USD' + string: \$ 118.73 USD downloadFiles: - id: 5e9a5eba75e0ac242e1b6f64 name: New product guide @@ -417,7 +428,9 @@ service: get: path: /sites/{site_id}/orders/{order_id} method: GET - auth: true + auth: + - OAuth2: + - ecommerce:read docs: | Retrieve a single product by its ID. All of its SKUs will also be retrieved. @@ -436,6 +449,7 @@ service: response: docs: Request was successful type: root.Order + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -468,15 +482,15 @@ service: customerPaid: unit: USD value: '5892' - string: ' 118.73 USD' + string: \$ 118.73 USD netAmount: unit: USD value: '5892' - string: ' 112.62 USD' + string: \$ 112.62 USD applicationFee: unit: USD value: '5892' - string: ' 2.37 USD' + string: \$ 2.37 USD allAddresses: - type: billing japanType: kana @@ -527,7 +541,7 @@ service: rowTotal: unit: USD value: '5892' - string: ' 55.61 USD' + string: \$ 55.61 USD productId: 66072fb61b89448912e26791 productName: Luxurious Fresh Ball productSlug: luxurious-fresh-ball @@ -537,11 +551,11 @@ service: variantSKU: luxurious-fresh-ball-generic-bronze-practical-plastic variantImage: url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg + https://dev-assets.website-files.com/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg variantPrice: unit: USD value: '5892' - string: ' 55.61 USD' + string: \$ 55.61 USD weight: 11 width: 82 height: 70 @@ -550,7 +564,7 @@ service: rowTotal: unit: USD value: '5892' - string: ' 53.44 USD' + string: \$ 53.44 USD productId: 66072fb61b89448912e26799 productName: Recycled Steel Gloves productSlug: recycled-steel-gloves @@ -560,11 +574,11 @@ service: variantSKU: recycled-steel-gloves-electronic-granite-handcrafted-grey variantImage: url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg + https://dev-assets.website-files.com/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg variantPrice: unit: USD value: '5892' - string: ' 53.44 USD' + string: \$ 53.44 USD weight: 38 width: 76 height: 85 @@ -605,7 +619,7 @@ service: subtotal: unit: USD value: '5892' - string: ' 109.05 USD' + string: \$ 109.05 USD extras: - type: tax name: State Taxes @@ -613,25 +627,25 @@ service: price: unit: USD value: '5892' - string: ' 4.36 USD' + string: \$ 4.36 USD - type: tax name: City Taxes description: NEW YORK Taxes (4.88%) price: unit: USD value: '5892' - string: ' 5.32 USD' + string: \$ 5.32 USD - type: shipping name: Flat description: '' price: unit: USD value: '5892' - string: ' 0.00 USD' + string: \$ 0.00 USD total: unit: USD value: '5892' - string: ' 118.73 USD' + string: \$ 118.73 USD downloadFiles: - id: 5e9a5eba75e0ac242e1b6f64 name: New product guide @@ -640,7 +654,9 @@ service: update: path: /sites/{site_id}/orders/{order_id} method: PATCH - auth: true + auth: + - OAuth2: + - ecommerce:write docs: | This API lets you update the fields, `comment`, `shippingProvider`, and/or `shippingTracking` for a given order. All three fields can be @@ -677,6 +693,7 @@ service: response: docs: Request was successful type: root.Order + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -710,15 +727,15 @@ service: customerPaid: unit: USD value: '5892' - string: ' 118.73 USD' + string: \$ 118.73 USD netAmount: unit: USD value: '5892' - string: ' 112.62 USD' + string: \$ 112.62 USD applicationFee: unit: USD value: '5892' - string: ' 2.37 USD' + string: \$ 2.37 USD allAddresses: - type: billing japanType: kana @@ -769,7 +786,7 @@ service: rowTotal: unit: USD value: '5892' - string: ' 55.61 USD' + string: \$ 55.61 USD productId: 66072fb61b89448912e26791 productName: Luxurious Fresh Ball productSlug: luxurious-fresh-ball @@ -779,11 +796,11 @@ service: variantSKU: luxurious-fresh-ball-generic-bronze-practical-plastic variantImage: url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg + https://dev-assets.website-files.com/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg variantPrice: unit: USD value: '5892' - string: ' 55.61 USD' + string: \$ 55.61 USD weight: 11 width: 82 height: 70 @@ -792,7 +809,7 @@ service: rowTotal: unit: USD value: '5892' - string: ' 53.44 USD' + string: \$ 53.44 USD productId: 66072fb61b89448912e26799 productName: Recycled Steel Gloves productSlug: recycled-steel-gloves @@ -802,11 +819,11 @@ service: variantSKU: recycled-steel-gloves-electronic-granite-handcrafted-grey variantImage: url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg + https://dev-assets.website-files.com/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg variantPrice: unit: USD value: '5892' - string: ' 53.44 USD' + string: \$ 53.44 USD weight: 38 width: 76 height: 85 @@ -847,7 +864,7 @@ service: subtotal: unit: USD value: '5892' - string: ' 109.05 USD' + string: \$ 109.05 USD extras: - type: tax name: State Taxes @@ -855,25 +872,25 @@ service: price: unit: USD value: '5892' - string: ' 4.36 USD' + string: \$ 4.36 USD - type: tax name: City Taxes description: NEW YORK Taxes (4.88%) price: unit: USD value: '5892' - string: ' 5.32 USD' + string: \$ 5.32 USD - type: shipping name: Flat description: '' price: unit: USD value: '5892' - string: ' 0.00 USD' + string: \$ 0.00 USD total: unit: USD value: '5892' - string: ' 118.73 USD' + string: \$ 118.73 USD downloadFiles: - id: 5e9a5eba75e0ac242e1b6f64 name: New product guide @@ -882,7 +899,9 @@ service: update-fulfill: path: /sites/{site_id}/orders/{order_id}/fulfill method: POST - auth: true + auth: + - OAuth2: + - ecommerce:write docs: | Updates an order's status to fulfilled @@ -909,6 +928,7 @@ service: response: docs: Request was successful type: root.Order + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -942,15 +962,15 @@ service: customerPaid: unit: USD value: '5892' - string: ' 118.73 USD' + string: \$ 118.73 USD netAmount: unit: USD value: '5892' - string: ' 112.62 USD' + string: \$ 112.62 USD applicationFee: unit: USD value: '5892' - string: ' 2.37 USD' + string: \$ 2.37 USD allAddresses: - type: billing japanType: kana @@ -1001,7 +1021,7 @@ service: rowTotal: unit: USD value: '5892' - string: ' 55.61 USD' + string: \$ 55.61 USD productId: 66072fb61b89448912e26791 productName: Luxurious Fresh Ball productSlug: luxurious-fresh-ball @@ -1011,11 +1031,11 @@ service: variantSKU: luxurious-fresh-ball-generic-bronze-practical-plastic variantImage: url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg + https://dev-assets.website-files.com/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg variantPrice: unit: USD value: '5892' - string: ' 55.61 USD' + string: \$ 55.61 USD weight: 11 width: 82 height: 70 @@ -1024,7 +1044,7 @@ service: rowTotal: unit: USD value: '5892' - string: ' 53.44 USD' + string: \$ 53.44 USD productId: 66072fb61b89448912e26799 productName: Recycled Steel Gloves productSlug: recycled-steel-gloves @@ -1034,11 +1054,11 @@ service: variantSKU: recycled-steel-gloves-electronic-granite-handcrafted-grey variantImage: url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg + https://dev-assets.website-files.com/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg variantPrice: unit: USD value: '5892' - string: ' 53.44 USD' + string: \$ 53.44 USD weight: 38 width: 76 height: 85 @@ -1079,7 +1099,7 @@ service: subtotal: unit: USD value: '5892' - string: ' 109.05 USD' + string: \$ 109.05 USD extras: - type: tax name: State Taxes @@ -1087,25 +1107,25 @@ service: price: unit: USD value: '5892' - string: ' 4.36 USD' + string: \$ 4.36 USD - type: tax name: City Taxes description: NEW YORK Taxes (4.88%) price: unit: USD value: '5892' - string: ' 5.32 USD' + string: \$ 5.32 USD - type: shipping name: Flat description: '' price: unit: USD value: '5892' - string: ' 0.00 USD' + string: \$ 0.00 USD total: unit: USD value: '5892' - string: ' 118.73 USD' + string: \$ 118.73 USD downloadFiles: - id: 5e9a5eba75e0ac242e1b6f64 name: New product guide @@ -1114,7 +1134,9 @@ service: update-unfulfill: path: /sites/{site_id}/orders/{order_id}/unfulfill method: POST - auth: true + auth: + - OAuth2: + - ecommerce:write docs: | Updates an order's status to unfulfilled @@ -1132,6 +1154,7 @@ service: response: docs: Request was successful type: root.Order + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -1164,15 +1187,15 @@ service: customerPaid: unit: USD value: '5892' - string: ' 118.73 USD' + string: \$ 118.73 USD netAmount: unit: USD value: '5892' - string: ' 112.62 USD' + string: \$ 112.62 USD applicationFee: unit: USD value: '5892' - string: ' 2.37 USD' + string: \$ 2.37 USD allAddresses: - type: billing japanType: kana @@ -1223,7 +1246,7 @@ service: rowTotal: unit: USD value: '5892' - string: ' 55.61 USD' + string: \$ 55.61 USD productId: 66072fb61b89448912e26791 productName: Luxurious Fresh Ball productSlug: luxurious-fresh-ball @@ -1233,11 +1256,11 @@ service: variantSKU: luxurious-fresh-ball-generic-bronze-practical-plastic variantImage: url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg + https://dev-assets.website-files.com/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg variantPrice: unit: USD value: '5892' - string: ' 55.61 USD' + string: \$ 55.61 USD weight: 11 width: 82 height: 70 @@ -1246,7 +1269,7 @@ service: rowTotal: unit: USD value: '5892' - string: ' 53.44 USD' + string: \$ 53.44 USD productId: 66072fb61b89448912e26799 productName: Recycled Steel Gloves productSlug: recycled-steel-gloves @@ -1256,11 +1279,11 @@ service: variantSKU: recycled-steel-gloves-electronic-granite-handcrafted-grey variantImage: url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg + https://dev-assets.website-files.com/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg variantPrice: unit: USD value: '5892' - string: ' 53.44 USD' + string: \$ 53.44 USD weight: 38 width: 76 height: 85 @@ -1301,7 +1324,7 @@ service: subtotal: unit: USD value: '5892' - string: ' 109.05 USD' + string: \$ 109.05 USD extras: - type: tax name: State Taxes @@ -1309,25 +1332,25 @@ service: price: unit: USD value: '5892' - string: ' 4.36 USD' + string: \$ 4.36 USD - type: tax name: City Taxes description: NEW YORK Taxes (4.88%) price: unit: USD value: '5892' - string: ' 5.32 USD' + string: \$ 5.32 USD - type: shipping name: Flat description: '' price: unit: USD value: '5892' - string: ' 0.00 USD' + string: \$ 0.00 USD total: unit: USD value: '5892' - string: ' 118.73 USD' + string: \$ 118.73 USD downloadFiles: - id: 5e9a5eba75e0ac242e1b6f64 name: New product guide @@ -1336,7 +1359,9 @@ service: refund: path: /sites/{site_id}/orders/{order_id}/refund method: POST - auth: true + auth: + - OAuth2: + - ecommerce:write docs: | This API will reverse a Stripe charge and refund an order back to a customer. It will also set the order's status to `refunded`. @@ -1363,6 +1388,7 @@ service: response: docs: Request was successful type: root.Order + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -1396,15 +1422,15 @@ service: customerPaid: unit: USD value: '5892' - string: ' 118.73 USD' + string: \$ 118.73 USD netAmount: unit: USD value: '5892' - string: ' 112.62 USD' + string: \$ 112.62 USD applicationFee: unit: USD value: '5892' - string: ' 2.37 USD' + string: \$ 2.37 USD allAddresses: - type: billing japanType: kana @@ -1455,7 +1481,7 @@ service: rowTotal: unit: USD value: '5892' - string: ' 55.61 USD' + string: \$ 55.61 USD productId: 66072fb61b89448912e26791 productName: Luxurious Fresh Ball productSlug: luxurious-fresh-ball @@ -1465,11 +1491,11 @@ service: variantSKU: luxurious-fresh-ball-generic-bronze-practical-plastic variantImage: url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg + https://dev-assets.website-files.com/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg variantPrice: unit: USD value: '5892' - string: ' 55.61 USD' + string: \$ 55.61 USD weight: 11 width: 82 height: 70 @@ -1478,7 +1504,7 @@ service: rowTotal: unit: USD value: '5892' - string: ' 53.44 USD' + string: \$ 53.44 USD productId: 66072fb61b89448912e26799 productName: Recycled Steel Gloves productSlug: recycled-steel-gloves @@ -1488,11 +1514,11 @@ service: variantSKU: recycled-steel-gloves-electronic-granite-handcrafted-grey variantImage: url: >- - https://d1otoma47x30pg.cloudfront.net/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg + https://dev-assets.website-files.com/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg variantPrice: unit: USD value: '5892' - string: ' 53.44 USD' + string: \$ 53.44 USD weight: 38 width: 76 height: 85 @@ -1533,7 +1559,7 @@ service: subtotal: unit: USD value: '5892' - string: ' 109.05 USD' + string: \$ 109.05 USD extras: - type: tax name: State Taxes @@ -1541,25 +1567,25 @@ service: price: unit: USD value: '5892' - string: ' 4.36 USD' + string: \$ 4.36 USD - type: tax name: City Taxes description: NEW YORK Taxes (4.88%) price: unit: USD value: '5892' - string: ' 5.32 USD' + string: \$ 5.32 USD - type: shipping name: Flat description: '' price: unit: USD value: '5892' - string: ' 0.00 USD' + string: \$ 0.00 USD total: unit: USD value: '5892' - string: ' 118.73 USD' + string: \$ 118.73 USD downloadFiles: - id: 5e9a5eba75e0ac242e1b6f64 name: New product guide @@ -1569,3 +1595,377 @@ service: openapi: ../../../openapi/referenced-specs/v2.yml display-name: Orders docs: Orders are the orders for your Webflow site. +webhooks: + ecomm_new_order: + audiences: [] + method: POST + display-name: New eComm Order + headers: {} + payload: root.NewOrder + examples: + - payload: + triggerType: ecomm_new_order + payload: + orderId: fc7-128 + status: unfulfilled + comment: >- + Customer requested gift wrapping and a personalized note saying: + Happy Birthday, Ford! 🎉 Please ensure the item is packed with + extra bubble wrap for safe transit. + orderComment: >- + Please gift wrap with a personal note saying "Happy Birthday, + Ford! 🎉 + acceptedOn: '2024-03-29T21:29:21Z' + fulfilledOn: '2018-12-03T22:06:15Z' + refundedOn: '2018-12-03T22:06:15Z' + disputedOn: '2018-12-03T22:06:15Z' + disputeUpdatedOn: '2018-12-03T22:06:15Z' + customerPaid: + unit: USD + value: '5892' + string: \$ 118.73 USD + netAmount: + unit: USD + value: '5892' + string: \$ 112.62 USD + applicationFee: + unit: USD + value: '5892' + string: \$ 2.37 USD + allAddresses: + - type: billing + addressee: Arthur Dent + line1: 20 W 34th St + line2: Empire State Building + city: New York + state: New York + country: US + postalCode: '10118' + - type: shipping + addressee: Arthur Dent + line1: 20 W 34th St + line2: Empire State Building + city: New York + state: New York + country: US + postalCode: '10118' + shippingAddress: + type: shipping + japanType: kanji + addressee: Arthur Dent + line1: 20 W 34th St + line2: Empire State Building + city: New York + state: New York + country: US + postalCode: '10118' + billingAddress: + type: billing + addressee: Arthur Dent + line1: 20 W 34th St + line2: Empire State Building + city: New York + state: New York + country: US + postalCode: '10118' + shippingProvider: Shipping Company, Co. + shippingTracking: tr00000000001 + shippingTrackingURL: https://www.shippingcompany.com/tracking/tr00000000001 + customerInfo: + fullName: Arthur Dent + email: arthur.dent@example.com + purchasedItems: + - count: 1 + rowTotal: + unit: USD + value: '5892' + string: \$ 55.61 USD + productId: 66072fb61b89448912e26791 + productName: Luxurious Fresh Ball + productSlug: luxurious-fresh-ball + variantId: 66072fb71b89448912e2683f + variantName: 'Luxurious Fresh Ball Generic: Bronze, Practical: Plastic' + variantSlug: luxurious-fresh-ball-generic-bronze-practical-plastic + variantSKU: luxurious-fresh-ball-generic-bronze-practical-plastic + variantImage: + url: >- + https://dev-assets.website-files.com/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg + variantPrice: + unit: USD + value: '5892' + string: \$ 55.61 USD + weight: 11 + width: 82 + height: 70 + length: 9 + - count: 1 + rowTotal: + unit: USD + value: '5892' + string: \$ 53.44 USD + productId: 66072fb61b89448912e26799 + productName: Recycled Steel Gloves + productSlug: recycled-steel-gloves + variantId: 66072fb91b89448912e26ab9 + variantName: 'Recycled Steel Gloves Electronic: Granite, Handcrafted: grey' + variantSlug: recycled-steel-gloves-electronic-granite-handcrafted-grey + variantSKU: recycled-steel-gloves-electronic-granite-handcrafted-grey + variantImage: + url: >- + https://dev-assets.website-files.com/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg + variantPrice: + unit: USD + value: '5892' + string: \$ 53.44 USD + weight: 38 + width: 76 + height: 85 + length: 40 + purchasedItemsCount: 2 + stripeDetails: + subscriptionId: sub_1J6xwG2eZvKYlo2CXu9Zt0Tn + paymentMethod: pm_1OzmzBJYFi4lcbXWHKNdXU7j + paymentIntentId: pi_3OzmzDJYFi4lcbXW1hTBW6ft + customerId: cus_PpRsNHwWdUoRKR + chargeId: ch_3OzmzDJYFi4lcbXW1ndkkrH2 + refundId: re_3OzmzDJYFi4lcbXW1kFAmlBk + refundReason: fraudulent + stripeCard: + last4: '4242' + brand: Visa + ownerName: Arthur Dent + expires: + year: 2024 + month: 4 + customData: + - key: value + metadata: + isBuyNow: false + isCustomerDeleted: false + isShippingRequired: true + hasDownloads: false + paymentProcessor: stripe + totals: + subtotal: + unit: USD + value: '5892' + string: \$ 109.05 USD + extras: + - type: tax + name: State Taxes + description: NY Taxes (4.00%) + price: + unit: USD + value: '5892' + string: \$ 4.36 USD + - type: tax + name: City Taxes + description: NEW YORK Taxes (4.88%) + price: + unit: USD + value: '5892' + string: \$ 5.32 USD + - type: shipping + name: Flat + description: '' + price: + unit: USD + value: '5892' + string: \$ 0.00 USD + total: + unit: USD + value: '5892' + string: \$ 118.73 USD + downloadFiles: + - id: 5e9a5eba75e0ac242e1b6f64 + name: New product guide + url: >- + https://webflow.com/dashboard/download-digital-product?payload=5d93ba5e38c6b0160ab711d3;e7634a;5eb1aac72912ec06f561278c;5e9a5eba75e0ac242e1b6f63:ka2nehxy:4a1ee0a632feaab94294350087215ed89533f2f530903e3b933b638940e921aa + docs: Information about a new ecommerce order + ecomm_order_changed: + audiences: [] + method: POST + display-name: Updated eComm Order + headers: {} + payload: root.UpdatedOrder + examples: + - payload: + triggerType: ecomm_order_changed + payload: + orderId: fc7-128 + status: refunded + comment: >- + Customer requested gift wrapping and a personalized note saying: + Happy Birthday, Ford! 🎉 Please ensure the item is packed with + extra bubble wrap for safe transit. + orderComment: >- + Please gift wrap with a personal note saying "Happy Birthday, + Ford! 🎉 + acceptedOn: '2024-03-29T21:29:21Z' + fulfilledOn: '2024-03-29T21:29:21Z' + refundedOn: '2024-04-08T18:25:04Z' + disputedOn: '2024-03-29T21:29:21Z' + disputeUpdatedOn: '2024-03-29T21:29:21Z' + disputeLastStatus: charge_refunded + customerPaid: + unit: USD + value: '5892' + string: \$ 118.73 USD + netAmount: + unit: USD + value: '5892' + string: \$ 112.62 USD + applicationFee: + unit: USD + value: '5892' + string: \$ 2.37 USD + allAddresses: + - type: billing + addressee: Arthur Dent + line1: 20 W 34th St + line2: Empire State Building + city: New York + state: New York + country: US + postalCode: '10118' + - type: shipping + addressee: Arthur Dent + line1: 20 W 34th St + line2: Empire State Building + city: New York + state: New York + country: US + postalCode: '10118' + shippingAddress: + type: shipping + japanType: kanji + addressee: Arthur Dent + line1: 20 W 34th St + line2: Empire State Building + city: New York + state: New York + country: US + postalCode: '10118' + billingAddress: + type: billing + addressee: Arthur Dent + line1: 20 W 34th St + line2: Empire State Building + city: New York + state: New York + country: US + postalCode: '10118' + shippingProvider: Shipping Company, Co. + shippingTracking: tr00000000001 + shippingTrackingURL: https://www.shippingcompany.com/tracking/tr00000000001 + customerInfo: + fullName: Arthur Dent + email: arthur.dent@example.com + purchasedItems: + - count: 1 + rowTotal: + unit: USD + value: '5892' + string: \$ 55.61 USD + productId: 66072fb61b89448912e26791 + productName: Luxurious Fresh Ball + productSlug: luxurious-fresh-ball + variantId: 66072fb71b89448912e2683f + variantName: 'Luxurious Fresh Ball Generic: Bronze, Practical: Plastic' + variantSlug: luxurious-fresh-ball-generic-bronze-practical-plastic + variantSKU: luxurious-fresh-ball-generic-bronze-practical-plastic + variantImage: + url: >- + https://dev-assets.website-files.com/66072f39417a2a35b2589cc7/66072fb51b89448912e2672c_image14.jpeg + variantPrice: + unit: USD + value: '5892' + string: \$ 55.61 USD + weight: 11 + width: 82 + height: 70 + length: 9 + - count: 1 + rowTotal: + unit: USD + value: '5892' + string: \$ 53.44 USD + productId: 66072fb61b89448912e26799 + productName: Recycled Steel Gloves + productSlug: recycled-steel-gloves + variantId: 66072fb91b89448912e26ab9 + variantName: 'Recycled Steel Gloves Electronic: Granite, Handcrafted: grey' + variantSlug: recycled-steel-gloves-electronic-granite-handcrafted-grey + variantSKU: recycled-steel-gloves-electronic-granite-handcrafted-grey + variantImage: + url: >- + https://dev-assets.website-files.com/66072f39417a2a35b2589cc7/66072fb51b89448912e2671e_image2.jpeg + variantPrice: + unit: USD + value: '5892' + string: \$ 53.44 USD + weight: 38 + width: 76 + height: 85 + length: 40 + purchasedItemsCount: 2 + stripeDetails: + subscriptionId: sub_1J6xwG2eZvKYlo2CXu9Zt0Tn + paymentMethod: pm_1OzmzBJYFi4lcbXWHKNdXU7j + paymentIntentId: pi_3OzmzDJYFi4lcbXW1hTBW6ft + customerId: cus_PpRsNHwWdUoRKR + chargeId: ch_3OzmzDJYFi4lcbXW1ndkkrH2 + refundId: re_3OzmzDJYFi4lcbXW1kFAmlBk + refundReason: fraudulent + stripeCard: + last4: '4242' + brand: Visa + ownerName: Arthur Dent + expires: + year: 2024 + month: 4 + customData: + - key: value + metadata: + isBuyNow: false + isCustomerDeleted: false + isShippingRequired: true + hasDownloads: false + paymentProcessor: stripe + totals: + subtotal: + unit: USD + value: '5892' + string: \$ 109.05 USD + extras: + - type: tax + name: State Taxes + description: NY Taxes (4.00%) + price: + unit: USD + value: '5892' + string: \$ 4.36 USD + - type: tax + name: City Taxes + description: NEW YORK Taxes (4.88%) + price: + unit: USD + value: '5892' + string: \$ 5.32 USD + - type: shipping + name: Flat + description: '' + price: + unit: USD + value: '5892' + string: \$ 0.00 USD + total: + unit: USD + value: '5892' + string: \$ 118.73 USD + downloadFiles: + - id: 5e9a5eba75e0ac242e1b6f64 + name: New product guide + url: >- + https://webflow.com/dashboard/download-digital-product?payload=5d93ba5e38c6b0160ab711d3;e7634a;5eb1aac72912ec06f561278c;5e9a5eba75e0ac242e1b6f63:ka2nehxy:4a1ee0a632feaab94294350087215ed89533f2f530903e3b933b638940e921aa + docs: Information about an updated ecommerce order diff --git a/.mock/definition/pages.yml b/.mock/definition/pages.yml index 62de7dc..12d954e 100644 --- a/.mock/definition/pages.yml +++ b/.mock/definition/pages.yml @@ -7,7 +7,9 @@ service: list: path: /sites/{site_id}/pages method: GET - auth: true + auth: + - OAuth2: + - page:read docs: | List of all pages for a site. @@ -24,20 +26,24 @@ service: query-parameters: localeId: type: optional - docs: >- - Unique identifier for a specific locale. Applicable, when using - localization. + docs: > + Unique identifier for a specific Locale. + + + [Lear more about + localization.](/data/v2.0.0/docs/working-with-localization) limit: - type: optional + type: optional docs: 'Maximum number of records to be returned (max limit: 100)' offset: - type: optional + type: optional docs: >- Offset used for pagination if the results have more than limit records response: docs: Request was successful type: root.PageList + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -49,6 +55,8 @@ service: site_id: 580e63e98c9a982ac9b8b741 query-parameters: localeId: 65427cf400e02b306eaa04a0 + limit: 1 + offset: 1 response: body: pages: @@ -62,9 +70,9 @@ service: lastUpdated: '2024-03-11T10:42:42Z' archived: false draft: false - canBranch: true - isBranch: false - isMembersOnly: false + canBranch: false + isBranch: true + branchId: 68026fa68ef6dc744c75b833 seo: title: The Ultimate Hitchhiker's Guide to the Galaxy description: >- @@ -91,7 +99,7 @@ service: draft: false canBranch: true isBranch: false - isMembersOnly: false + branchId: 68026fa68ef6dc744c75b833 seo: title: Celebrate Towel Day - The Hitchhiker's Guide to the Galaxy description: >- @@ -115,7 +123,9 @@ service: get-metadata: path: /pages/{page_id} method: GET - auth: true + auth: + - OAuth2: + - page:read docs: | Get metadata information for a single page. @@ -132,12 +142,16 @@ service: query-parameters: localeId: type: optional - docs: >- - Unique identifier for a specific locale. Applicable, when using - localization. + docs: > + Unique identifier for a specific Locale. + + + [Lear more about + localization.](/data/v2.0.0/docs/working-with-localization) response: docs: Request was successful type: root.Page + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -161,9 +175,9 @@ service: lastUpdated: '2024-03-11T10:42:42Z' archived: false draft: false - canBranch: true - isBranch: false - isMembersOnly: false + canBranch: false + isBranch: true + branchId: 68026fa68ef6dc744c75b833 seo: title: The Ultimate Hitchhiker's Guide to the Galaxy description: >- @@ -181,7 +195,9 @@ service: update-page-settings: path: /pages/{page_id} method: PUT - auth: true + auth: + - OAuth2: + - page:write docs: | Update Page-level metadata, including SEO and Open Graph fields. @@ -194,18 +210,42 @@ service: docs: Unique identifier for a Page display-name: Update Page Metadata request: - body: root.Page + name: PageMetadataWrite query-parameters: localeId: type: optional - docs: >- - Unique identifier for a specific locale. Applicable, when using - localization. - name: UpdatePageSettingsRequest + docs: > + Unique identifier for a specific Locale. + + + [Lear more about + localization.](/data/v2.0.0/docs/working-with-localization) + body: + properties: + title: + type: optional + docs: Title for the page + slug: + type: optional + docs: > + Slug for the page. + + + + **Note:** Updating slugs in secondary locales is only supported + in Advanced and + Enterprise localization add-on plans. + seo: + type: optional + docs: SEO-related fields for the Page + openGraph: + type: optional + docs: Open Graph fields for the Page content-type: application/json response: docs: Request was successful type: root.Page + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -218,16 +258,8 @@ service: query-parameters: localeId: 65427cf400e02b306eaa04a0 request: - id: 6596da6045e56dee495bcbba - siteId: 6258612d1ee792848f805dcf title: Guide to the Galaxy slug: guide-to-the-galaxy - createdOn: '2024-03-11T10:42:00Z' - lastUpdated: '2024-03-11T10:42:42Z' - archived: false - draft: false - canBranch: true - isBranch: false seo: title: The Ultimate Hitchhiker's Guide to the Galaxy description: >- @@ -240,8 +272,6 @@ service: Dive deep into the mysteries of the universe with your guide to everything galactic. descriptionCopied: false - localeId: 653fd9af6a07fc9cfd7a5e57 - publishedPath: /en-us/guide-to-the-galaxy response: body: id: 6596da6045e56dee495bcbba @@ -254,9 +284,9 @@ service: lastUpdated: '2024-03-11T10:42:42Z' archived: false draft: false - canBranch: true - isBranch: false - isMembersOnly: false + canBranch: false + isBranch: true + branchId: 68026fa68ef6dc744c75b833 seo: title: The Ultimate Hitchhiker's Guide to the Galaxy description: >- @@ -274,21 +304,13 @@ service: get-content: path: /pages/{page_id}/dom method: GET - auth: true - docs: > - Get static content from a static page. This includes text nodes, image - nodes and component instances. - - To retrieve the contents of components in the page use the [get - component - content](/data/reference/pages-and-components/components/get-content) - endpoint. - - - If you do not provide a Locale ID in your request, the response - will return any content that can be localized from the Primary - locale. + auth: + - OAuth2: + - page:read + docs: | + Get text and component instance content from a static page. + Localization Required scope | `pages:read` source: @@ -303,20 +325,24 @@ service: query-parameters: localeId: type: optional - docs: >- - Unique identifier for a specific locale. Applicable, when using - localization. + docs: > + Unique identifier for a specific Locale. + + + [Lear more about + localization.](/data/v2.0.0/docs/working-with-localization) limit: - type: optional + type: optional docs: 'Maximum number of records to be returned (max limit: 100)' offset: - type: optional + type: optional docs: >- Offset used for pagination if the results have more than limit records response: docs: Request was successful type: root.Dom + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -325,52 +351,65 @@ service: - root.TooManyRequestsError - root.InternalServerError examples: - - name: PageDOM - path-parameters: + - path-parameters: page_id: 63c720f9347c2139b248e552 query-parameters: localeId: 65427cf400e02b306eaa04a0 + limit: 1 + offset: 1 response: body: pageId: 658205daa3e8206a523b5ad4 + branchId: 68026fa68ef6dc744c75b833 nodes: - - type: component-instance - id: a245c12d-995b-55ee-5ec7-aa36a6cad623 - componentId: nodes + - id: id + text: {} + attributes: + key: value + type: text + - id: id + text: {} + attributes: + key: value + type: text + - id: id + image: {} + attributes: + key: value + type: image + - id: id + choices: + - value: value + text: text + attributes: + key: value + type: select + - id: id + placeholder: placeholder + attributes: + key: value + type: text-input + - id: id + text: {} + attributes: + key: value + type: text + - id: id + componentId: componentId propertyOverrides: - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 - - type: component-instance - id: a245c12d-995b-55ee-5ec7-aa36a6cad627 - componentId: nodes - propertyOverrides: - - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 - - type: component-instance - id: a245c12d-995b-55ee-5ec7-aa36a6cad629 - componentId: nodes - propertyOverrides: - - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 - - type: component-instance - id: a245c12d-995b-55ee-5ec7-aa36a6cad631 - componentId: 6258612d1ee792848f805dcf - propertyOverrides: - - propertyId: a245c12d-995b-55ee-5ec7-aa36a6cad633 - type: Plain Text - label: Catchphrase - text: - text: Don't Panic! - - propertyId: a245c12d-995b-55ee-5ec7-aa36a6cad635 - type: Rich Text - label: Tagline - text: - html:

Always know where your towel is.

+ type: component-instance pagination: limit: 4 offset: 0 total: 4 + lastUpdated: '2016-10-24T19:42:38Z' update-static-content: path: /pages/{page_id}/dom method: POST - auth: true + auth: + - OAuth2: + - page:write docs: > This endpoint updates content on a static page in **secondary locales**. It supports updating up to 1000 nodes in a single request. @@ -380,12 +419,17 @@ service: 1. Use the [get page content](/data/reference/pages-and-components/pages/get-content) - endpoint to identify available content nodes and their types + endpoint to identify available content nodes and their types. 2. If the page has component instances, retrieve the component's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) - endpoint + endpoint. + + 3. DOM elements may include a `data-w-id` attribute. This attribute is + used by Webflow to maintain custom attributes and links across locales. + Always include the original `data-w-id` value in your update requests to + ensure consistent behavior across all locales. @@ -418,6 +462,7 @@ service: response: docs: Request was successful type: UpdateStaticContentResponse + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -438,6 +483,17 @@ service: text: >-

Don't Panic!

Always know where your towel is.

+ - nodeId: a245c12d-995b-55ee-5ec7-aa36a6cad635 + choices: + - value: choice-1 + text: First choice + - value: choice-2 + text: Second choice + - nodeId: a245c12d-995b-55ee-5ec7-aa36a6cad642 + placeholder: Enter something here... + - nodeId: a245c12d-995b-55ee-5ec7-aa36a6cad671 + value: Submit + waitingText: Submitting... - nodeId: a245c12d-995b-55ee-5ec7-aa36a6cad629 propertyOverrides: - propertyId: 7dd14c08-2e96-8d3d-2b19-b5c03642a0f0 @@ -453,11 +509,47 @@ service: display-name: Pages docs: Pages are the pages in your Webflow site. types: + PageMetadataWriteSeo: + docs: SEO-related fields for the Page + properties: + title: + type: optional + docs: The Page title shown in search engine results + description: + type: optional + docs: The Page description shown in search engine results + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + PageMetadataWriteOpenGraph: + docs: Open Graph fields for the Page + properties: + title: + type: optional + docs: The title supplied to Open Graph annotations + titleCopied: + type: optional + docs: Indicates the Open Graph title was copied from the SEO title + description: + type: optional + docs: The description supplied to Open Graph annotations + descriptionCopied: + type: optional + docs: >- + Indicates the Open Graph description was copied from the SEO + description + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true PageDomWriteNodesItem: discriminated: false union: - - root.TextNodeWrite - - root.ComponentInstanceNodePropertyOverridesWrite + - type: root.TextNodeWrite + - type: root.ComponentInstanceNodePropertyOverridesWrite + - type: root.Select + - type: root.TextInputNodeWrite + - type: root.SubmitButtonNodeWrite + - type: root.SearchButtonNodeWrite source: openapi: ../../../openapi/referenced-specs/v2.yml inline: true @@ -468,3 +560,52 @@ types: type: list source: openapi: ../../../openapi/referenced-specs/v2.yml +webhooks: + page_created: + audiences: [] + method: POST + display-name: Page Created + headers: {} + payload: root.PageCreatedWebhook + examples: + - payload: + triggerType: page_created + payload: + siteId: 65427cf400e02b306eaa049c + pageId: 66a3cfb276641574f5d58311 + pageTitle: Heart of Gold Specs + createdOn: '2024-07-26T16:32:50Z' + publishedPath: /blog/earth + docs: Information about a new pages + page_metadata_updated: + audiences: [] + method: POST + display-name: Page Metadata Updated + headers: {} + payload: root.PageMetadataUpdatedWebhook + examples: + - payload: + triggerType: page_metadata_updated + payload: + siteId: 65427cf400e02b306eaa049c + pageId: 66a3cfb276641574f5d58311 + pageTitle: Heart of Gold Specs + lastUpdated: '2024-07-26T16:32:50Z' + publishedPath: /blog/earth + docs: Information about a page's updated metadata and/or settings + page_deleted: + audiences: [] + method: POST + display-name: Page Deleted + headers: {} + payload: root.PageDeletedWebhook + examples: + - payload: + triggerType: page_deleted + payload: + siteId: 65427cf400e02b306eaa049c + pageId: 66a3cfb276641574f5d58311 + pageTitle: Heart of Gold Specs + deletedOn: '2024-07-26T16:32:50Z' + publishedPath: /blog/earth + docs: Information about a page that was deleted diff --git a/.mock/definition/pages/scripts.yml b/.mock/definition/pages/scripts.yml index f8ee328..59bc96a 100644 --- a/.mock/definition/pages/scripts.yml +++ b/.mock/definition/pages/scripts.yml @@ -7,23 +7,11 @@ service: get-custom-code: path: /pages/{page_id}/custom_code method: GET - auth: true - docs: > - Get all registered scripts that have been applied to a specific Page. - - - In order to use the Custom Code APIs for Sites and Pages, Custom Code - Scripts must first be registered - - to a Site via the `registered_scripts` endpoints, and then applied to a - Site or Page using the appropriate - - `custom_code` endpoints. - - - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). - + auth: + - OAuth2: + - custom_code:read + docs: | + Get all scripts applied to a page. Required scope | `custom_code:read` source: @@ -36,6 +24,7 @@ service: response: docs: Request was successful type: root.ScriptApplyList + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -58,25 +47,20 @@ service: upsert-custom-code: path: /pages/{page_id}/custom_code method: PUT - auth: true + auth: + - OAuth2: + - custom_code:write docs: > - Add a registered script to a Page. + Apply registered scripts to a page. If you have multiple scripts your + App needs to apply or maintain on a page, ensure they are always + included in the request body for this endpoint. To remove individual + scripts, simply call this endpoint without the script in the request + body. - In order to use the Custom Code APIs for Sites and Pages, Custom Code - Scripts must first be registered - - to a Site via the `registered_scripts` endpoints, and then applied to a - Site or Page using the appropriate - - `custom_code` endpoints. - - - A site can have a maximum of 800 registered scripts. - - - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). + + To apply a script to a page, the script must first be registered to a Site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` @@ -93,6 +77,7 @@ service: response: docs: Request was successful type: root.ScriptApplyList + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -131,22 +116,22 @@ service: delete-custom-code: path: /pages/{page_id}/custom_code method: DELETE - auth: true + auth: + - OAuth2: + - custom_code:write docs: > - Delete the custom code block that an app has created for a page - - - In order to use the Custom Code APIs for Sites and Pages, Custom Code - Scripts must first be registered + Remove all scripts from a page applied by the App. This endpoint will + not remove scripts from the site's registered scripts. - to a Site via the `registered_scripts` endpoints, and then applied to a - Site or Page using the appropriate - `custom_code` endpoints. + To remove individual scripts applied by the App, use the [Add/Update + Custom + Code](/data/reference/custom-code/custom-code-pages/upsert-custom-code) + endpoint. - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). + Access to this endpoint requires a bearer token obtained from an + [OAuth Code Grant Flow](/data/reference/oauth-app). Required scope | `custom_code:write` diff --git a/.mock/definition/products.yml b/.mock/definition/products.yml index 4c6fcd1..9474978 100644 --- a/.mock/definition/products.yml +++ b/.mock/definition/products.yml @@ -7,7 +7,9 @@ service: list: path: /sites/{site_id}/products method: GET - auth: true + auth: + - OAuth2: + - ecommerce:read docs: > Retrieve all products for a site. @@ -31,16 +33,17 @@ service: name: ProductsListRequest query-parameters: offset: - type: optional + type: optional docs: >- Offset used for pagination if the results have more than limit records limit: - type: optional + type: optional docs: 'Maximum number of records to be returned (max limit: 100)' response: docs: Request was successful type: root.ProductAndSkUsList + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -52,6 +55,9 @@ service: examples: - path-parameters: site_id: 580e63e98c9a982ac9b8b741 + query-parameters: + offset: 1 + limit: 1 response: body: items: @@ -72,24 +78,34 @@ service: - id: Color name: Color enum: - - id: id + - id: royal-blue name: Royal Blue slug: royal-blue skus: - - id: 580e63fc8c9a982ac9b8b745 + - id: 66072fb71b89448912e2681c cmsLocaleId: 653ad57de882f528b32e810e lastPublished: '2023-03-17T18:47:35Z' lastUpdated: '2023-03-17T18:47:35Z' createdOn: '2023-03-17T18:47:35Z' fieldData: sku-values: - ff42fee0113744f693a764e3431a9cc2: 64a74715c456e36762fc39a1 - name: Blue T-shirt - slug: t-shirt-blue + color: blue + size: small + name: Colorful T-shirt - Default + slug: colorful-t-shirt-default price: - value: 100 + value: 2499 unit: USD - quantity: 10 + currency: USD + main-image: https://www.example.com/image.jpg + sku: '1234567890' + sku-properties: + - id: Color + name: Color + enum: + - id: royal-blue + name: Royal Blue + slug: royal-blue pagination: limit: 100 offset: 0 @@ -97,22 +113,18 @@ service: create: path: /sites/{site_id}/products method: POST - auth: true + auth: + - OAuth2: + - ecommerce:write docs: > - Create a new product and SKU. + Create a new ecommerce product and defaultSKU. A product, at minimum, + must have a single SKU. - When you create a product, you will always create a SKU, since a Product - Item must have, at minimum, a single SKU. - - - To create a Product with multiple SKUs - for example a T-shirt in sizes - small, medium and large: - - Create parameters in `sku-properties`, also known as [product options and variants.](https://help.webflow.com/hc/en-us/articles/33961334531347-Create-product-options-and-variants). - - A single `sku-property` would be `color`. Within the `color` property, list the various colors of T-shirts as an array of `enum` values: `royal-blue`, `crimson-red`, and `forrest-green`. - - Once, you've created a Product and its `sku-properties` with `enum` values, Webflow will create a **default SKU**, which will automatically be a combination of the first `sku-properties` you've created. - - In our example, the default SKU will be a Royal Blue T-Shirt, because our first `enum` of our Color `sku-property` is Royal Blue. - - After you've created your product, you can create additional SKUs using the [Create SKU endpoint.](/data/reference/ecommerce/products/create-sku) + To create a product with multiple SKUs: + - First, create a list of `sku-properties`, also known as [product options](https://help.webflow.com/hc/en-us/articles/33961334531347-Create-product-options-and-variants). For example, a T-shirt product may have a "color" `sku-property`, with a list of enum values: red, yellow, and blue, another `sku-property` may be "size", with a list of enum values: small, medium, and large. + - Once, a product is created with a list of `sku-properties`, Webflow will create a **default SKU**, which is always a combination of the first `enum` values of each `sku-property`. (e.g. Small - Red - T-Shirt) + - After creation, you can create additional SKUs for the product, using the [Create SKUs endpoint.](/data/reference/ecommerce/products/create-sku) Upon creation, the default product type will be `Advanced`, which ensures all Product and SKU fields will be shown to users in the @@ -132,12 +144,13 @@ service: body: properties: publishStatus: optional - product: optional - sku: optional + product: ProductSkuCreateProduct + sku: ProductSkuCreateSku content-type: application/json response: docs: Request was successful type: root.ProductAndSkUs + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -149,7 +162,50 @@ service: examples: - path-parameters: site_id: 580e63e98c9a982ac9b8b741 - request: {} + request: + publishStatus: staging + product: + fieldData: + name: Colorful T-shirt + slug: colorful-t-shirt + description: >- + Our best-selling t-shirt available in multiple colors and + sizes + sku-properties: + - id: color + name: Color + enum: + - id: red + name: Red + slug: red + - id: yellow + name: Yellow + slug: yellow + - id: blue + name: Blue + slug: blue + - id: size + name: Size + enum: + - id: small + name: Small + slug: small + - id: medium + name: Medium + slug: medium + - id: large + name: Large + slug: large + sku: + fieldData: + name: Colorful T-shirt - Red Small + slug: colorful-t-shirt-red-small + price: + value: 2499 + unit: USD + currency: USD + main-image: >- + https://rocketamp-sample-store.myshopify.com/cdn/shop/products/Gildan_2000_Antique_Cherry_Red_Front_1024x1024.jpg?v=1527232987 response: body: product: @@ -169,33 +225,45 @@ service: - id: Color name: Color enum: - - id: id + - id: royal-blue name: Royal Blue slug: royal-blue - categories: - - categories + category: + - category tax-category: standard-taxable default-sku: default-sku ec-product-type: ff42fee0113744f693a764e3431a9cc2 skus: - - id: 580e63fc8c9a982ac9b8b745 + - id: 66072fb71b89448912e2681c cmsLocaleId: 653ad57de882f528b32e810e lastPublished: '2023-03-17T18:47:35Z' lastUpdated: '2023-03-17T18:47:35Z' createdOn: '2023-03-17T18:47:35Z' fieldData: sku-values: - ff42fee0113744f693a764e3431a9cc2: 64a74715c456e36762fc39a1 - name: Blue T-shirt - slug: t-shirt-blue + color: blue + size: small + name: Colorful T-shirt - Default + slug: colorful-t-shirt-default price: - value: 100 + value: 2499 unit: USD - quantity: 10 + currency: USD + main-image: https://www.example.com/image.jpg + sku: '1234567890' + sku-properties: + - id: Color + name: Color + enum: + - id: royal-blue + name: Royal Blue + slug: royal-blue get: path: /sites/{site_id}/products/{product_id} method: GET - auth: true + auth: + - OAuth2: + - ecommerce:read docs: | Retrieve a single product by its ID. All of its SKUs will also be retrieved. @@ -214,6 +282,7 @@ service: response: docs: Request was successful type: root.ProductAndSkUs + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -245,33 +314,45 @@ service: - id: Color name: Color enum: - - id: id + - id: royal-blue name: Royal Blue slug: royal-blue - categories: - - categories + category: + - category tax-category: standard-taxable default-sku: default-sku ec-product-type: ff42fee0113744f693a764e3431a9cc2 skus: - - id: 580e63fc8c9a982ac9b8b745 + - id: 66072fb71b89448912e2681c cmsLocaleId: 653ad57de882f528b32e810e lastPublished: '2023-03-17T18:47:35Z' lastUpdated: '2023-03-17T18:47:35Z' createdOn: '2023-03-17T18:47:35Z' fieldData: sku-values: - ff42fee0113744f693a764e3431a9cc2: 64a74715c456e36762fc39a1 - name: Blue T-shirt - slug: t-shirt-blue + color: blue + size: small + name: Colorful T-shirt - Default + slug: colorful-t-shirt-default price: - value: 100 + value: 2499 unit: USD - quantity: 10 + currency: USD + main-image: https://www.example.com/image.jpg + sku: '1234567890' + sku-properties: + - id: Color + name: Color + enum: + - id: royal-blue + name: Royal Blue + slug: royal-blue update: path: /sites/{site_id}/products/{product_id} method: PATCH - auth: true + auth: + - OAuth2: + - ecommerce:write docs: > Update an existing Product. @@ -303,6 +384,7 @@ service: response: docs: Request was successful type: root.Product + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -334,18 +416,20 @@ service: - id: Color name: Color enum: - - id: id + - id: royal-blue name: Royal Blue slug: royal-blue - categories: - - categories + category: + - category tax-category: standard-taxable default-sku: default-sku ec-product-type: ff42fee0113744f693a764e3431a9cc2 create-sku: path: /sites/{site_id}/products/{product_id}/skus method: POST - auth: true + auth: + - OAuth2: + - ecommerce:write docs: > Create additional SKUs to manage every [option and variant of your Product.](https://help.webflow.com/hc/en-us/articles/33961334531347-Create-product-options-and-variants) @@ -366,7 +450,7 @@ service: product_id: type: string docs: Unique identifier for a Product - display-name: Create SKU + display-name: Create SKUs request: name: ProductsCreateSkuRequest body: @@ -379,6 +463,7 @@ service: response: docs: Request was successful type: ProductsCreateSkuResponse + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -393,28 +478,51 @@ service: product_id: 580e63fc8c9a982ac9b8b745 request: skus: - - {} + - id: 66072fb71b89448912e2681c + cmsLocaleId: 653ad57de882f528b32e810e + lastPublished: '2023-03-17T18:47:35Z' + lastUpdated: '2023-03-17T18:47:35Z' + createdOn: '2023-03-17T18:47:35Z' + fieldData: + name: Colorful T-shirt - Default + slug: colorful-t-shirt-default + price: + value: 2499 + unit: USD + currency: USD response: body: skus: - - id: 580e63fc8c9a982ac9b8b745 + - id: 66072fb71b89448912e2681c cmsLocaleId: 653ad57de882f528b32e810e lastPublished: '2023-03-17T18:47:35Z' lastUpdated: '2023-03-17T18:47:35Z' createdOn: '2023-03-17T18:47:35Z' fieldData: sku-values: - ff42fee0113744f693a764e3431a9cc2: 64a74715c456e36762fc39a1 - name: Blue T-shirt - slug: t-shirt-blue + color: blue + size: small + name: Colorful T-shirt - Default + slug: colorful-t-shirt-default price: - value: 100 + value: 2499 unit: USD - quantity: 10 + currency: USD + main-image: https://www.example.com/image.jpg + sku: '1234567890' + sku-properties: + - id: Color + name: Color + enum: + - id: royal-blue + name: Royal Blue + slug: royal-blue update-sku: path: /sites/{site_id}/products/{product_id}/skus/{sku_id} method: PATCH - auth: true + auth: + - OAuth2: + - ecommerce:write docs: > Update a specified SKU. @@ -448,6 +556,7 @@ service: response: docs: Request was successful type: root.Sku + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -462,22 +571,36 @@ service: product_id: 580e63fc8c9a982ac9b8b745 sku_id: 5e8518516e147040726cc415 request: - sku: {} + sku: + id: 66072fb71b89448912e2681c + cmsLocaleId: 653ad57de882f528b32e810e + lastPublished: '2023-03-17T18:47:35Z' + lastUpdated: '2023-03-17T18:47:35Z' + createdOn: '2023-03-17T18:47:35Z' + fieldData: + name: Colorful T-shirt - Default + slug: colorful-t-shirt-default + price: + value: 2499 + unit: USD + currency: USD response: body: - id: 580e63fc8c9a982ac9b8b745 + id: 66072fb71b89448912e2681c cmsLocaleId: 653ad57de882f528b32e810e lastPublished: '2023-03-17T18:47:35Z' lastUpdated: '2023-03-17T18:47:35Z' createdOn: '2023-03-17T18:47:35Z' fieldData: sku-values: - ff42fee0113744f693a764e3431a9cc2: 64a74715c456e36762fc39a1 - name: Blue T-shirt - slug: t-shirt-blue + color: blue + size: small + name: Colorful T-shirt - Default + slug: colorful-t-shirt-default price: - value: 100 + value: 2499 unit: USD + currency: USD compare-at-price: value: 100 unit: USD @@ -488,13 +611,32 @@ service: trial: 7 plans: - {} - track-inventory: true - quantity: 10 + main-image: https://www.example.com/image.jpg + sku: '1234567890' + sku-properties: + - id: Color + name: Color + enum: + - id: royal-blue + name: Royal Blue + slug: royal-blue source: openapi: ../../../openapi/referenced-specs/v2.yml types: + ProductSkuCreateProduct: + properties: + fieldData: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true + ProductSkuCreateSku: + properties: + fieldData: optional + source: + openapi: ../../../openapi/referenced-specs/v2.yml + inline: true ProductsCreateSkuResponse: properties: - skus: optional> + skus: list source: openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/scripts.yml b/.mock/definition/scripts.yml index 8236ed2..089d5f8 100644 --- a/.mock/definition/scripts.yml +++ b/.mock/definition/scripts.yml @@ -7,25 +7,17 @@ service: list: path: /sites/{site_id}/registered_scripts method: GET - auth: true + auth: + - OAuth2: + - custom_code:read docs: > - List of scripts registered to a Site. + Get a list of scripts that have been registered to a site. A site can + have a maximum of 800 registered scripts. - In order to use the Custom Code APIs for Sites and Pages, Custom Code - Scripts must first be registered - - to a Site via the `registered_scripts` endpoints, and then applied to a - Site or Page using the appropriate - - `custom_code` endpoints. - - Additionally, Scripts can be remotely hosted, or registered as inline - snippets. - - - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:read` @@ -39,6 +31,7 @@ service: response: docs: Request was successful type: root.RegisteredScriptList + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -76,29 +69,22 @@ service: createdOn: '2022-10-26T00:28:54.191Z' lastUpdated: lastUpdated version: 1.0.0 + pagination: + limit: 100 + offset: 0 + total: 3 register-hosted: path: /sites/{site_id}/registered_scripts/hosted method: POST - auth: true - docs: > - Add a script to a Site's Custom Code registry. - - - In order to use the Custom Code APIs for Sites and Pages, Custom Code - Scripts must first be registered - - to a Site via the `registered_scripts` endpoints, and then applied to a - Site or Page using the appropriate - - `custom_code` endpoints. - - Additionally, Scripts can be remotely hosted, or registered as inline - snippets. - - - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). + auth: + - OAuth2: + - custom_code:write + docs: | + Register a hosted script to a site. + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` source: @@ -138,6 +124,7 @@ service: response: docs: Request was successful type: root.CustomCodeHostedResponse + status-code: 201 errors: - root.BadRequestError - root.UnauthorizedError @@ -166,23 +153,17 @@ service: register-inline: path: /sites/{site_id}/registered_scripts/inline method: POST - auth: true + auth: + - OAuth2: + - custom_code:write docs: > - Add a script to a Site's Custom Code registry. Inline scripts can be - between 1 and 2000 characters. - + Register an inline script to a site. Inline scripts are limited to 2000 + characters. - In order to use the Custom Code APIs for Sites and Pages, Custom Code - Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a - Site or Page using the appropriate - - `custom_code` endpoints. - - - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` @@ -225,6 +206,7 @@ service: response: docs: Created type: root.CustomCodeInlineResponse + status-code: 201 errors: - root.BadRequestError - root.UnauthorizedError @@ -232,7 +214,8 @@ service: - root.TooManyRequestsError - root.InternalServerError examples: - - path-parameters: + - name: CustomCodeInlineResponse + path-parameters: site_id: 580e63e98c9a982ac9b8b741 request: sourceCode: alert('hello world'); diff --git a/.mock/definition/sites.yml b/.mock/definition/sites.yml index cea8997..ebc7cd0 100644 --- a/.mock/definition/sites.yml +++ b/.mock/definition/sites.yml @@ -7,9 +7,16 @@ service: create: path: /workspaces/{workspace_id}/sites method: POST - auth: true - docs: | - Create a site. This endpoint requires an Enterprise workspace. + auth: + - OAuth2: + - sites:write + docs: > + Create a site. + + + This endpoint requires an Enterprise + workspace. + Required scope | `workspace:write` source: @@ -36,6 +43,7 @@ service: response: docs: Request was successful type: root.Site + status-code: 201 errors: - root.BadRequestError - root.UnauthorizedError @@ -54,12 +62,12 @@ service: id: 670ecf86817e3cc7a510eb6a workspaceId: 625860a7a6c16d624927122f createdOn: '2024-10-15T20:24:38Z' - displayName: The Hitchiker‘s Guide + displayName: The Hitchiker's Guide shortName: hitchikers-guide lastPublished: '2016-10-24T19:43:17Z' lastUpdated: '2024-10-15T20:24:38Z' previewUrl: >- - https://d1otoma47x30pg.cloudfront.net/580e63e98c9a982ac9b8b741/201610241243.png + https://dev-assets.website-files.com/580e63e98c9a982ac9b8b741/201610241243.png timeZone: America/Los_Angeles parentFolderId: 670ece123598db72d9648be1 customDomains: @@ -84,12 +92,14 @@ service: redirect: true subdirectory: '' tag: en-US - dataCollectionEnabled: false + dataCollectionEnabled: true dataCollectionType: always list: path: /sites method: GET - auth: true + auth: + - OAuth2: + - sites:read docs: | List of all sites the provided access token is able to access. @@ -100,6 +110,7 @@ service: response: docs: Request was successful type: root.Sites + status-code: 200 errors: - root.UnauthorizedError - root.NotFoundError @@ -116,7 +127,7 @@ service: lastPublished: '2023-04-02T12:42:00Z' lastUpdated: '2016-10-24T19:43:17Z' previewUrl: >- - https://d1otoma47x30pg.cloudfront.net/42e63e98c9a982ac9b8b741/197910121200.png + https://dev-assets.website-files.com/42e63e98c9a982ac9b8b741/197910121200.png timeZone: DeepSpace/InfiniteImprobability parentFolderId: 1as2d3f4g5h6j7k8l9z0x1c2v3b4n5m6 customDomains: @@ -157,7 +168,7 @@ service: lastPublished: '2023-04-02T12:45:00Z' lastUpdated: '2016-10-24T19:43:17Z' previewUrl: >- - https://d1otoma47x30pg.cloudfront.net/42e63e98c9a982ac9b8b742/198110121200.png + https://dev-assets.website-files.com/42e63e98c9a982ac9b8b742/198110121200.png timeZone: DeepSpace/Depression parentFolderId: 1as2d3f4g5h6j7k8l9z0x1c2v3b4n5m6 customDomains: @@ -191,7 +202,7 @@ service: lastPublished: '2023-04-02T12:50:00Z' lastUpdated: '2016-10-24T19:43:17Z' previewUrl: >- - https://d1otoma47x30pg.cloudfront.net/42e63e98c9a982ac9b8b743/198210121200.png + https://dev-assets.website-files.com/42e63e98c9a982ac9b8b743/198210121200.png timeZone: Vogsphere/PoetryHall parentFolderId: 1as2d3f4g5h6j7k8l9z0x1c2v3b4n5m6 customDomains: @@ -220,7 +231,9 @@ service: get: path: /sites/{site_id} method: GET - auth: true + auth: + - OAuth2: + - sites:read docs: | Get details of a site. @@ -235,6 +248,7 @@ service: response: docs: Request was successful type: root.Site + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -242,7 +256,8 @@ service: - root.TooManyRequestsError - root.InternalServerError examples: - - path-parameters: + - name: SiteWithLocales + path-parameters: site_id: 580e63e98c9a982ac9b8b741 response: body: @@ -287,9 +302,16 @@ service: delete: path: /sites/{site_id} method: DELETE - auth: true - docs: | - Delete a site. This endpoint requires an Enterprise workspace. + auth: + - OAuth2: + - sites:write + docs: > + Delete a site. + + + This endpoint requires an Enterprise + workspace. + Required scope | `sites:write` source: @@ -312,9 +334,16 @@ service: update: path: /sites/{site_id} method: PATCH - auth: true - docs: | - Update a site. This endpoint requires an Enterprise workspace. + auth: + - OAuth2: + - sites:write + docs: > + Update a site. + + + This endpoint requires an Enterprise + workspace. + Required scope | `sites:write` source: @@ -338,6 +367,7 @@ service: response: docs: Request was successful type: root.Site + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -392,7 +422,9 @@ service: get-custom-domain: path: /sites/{site_id}/custom_domains method: GET - auth: true + auth: + - OAuth2: + - sites:read docs: | Get a list of all custom domains related to site. @@ -407,6 +439,7 @@ service: response: docs: Request was successful type: root.Domains + status-code: 200 errors: - root.UnauthorizedError - root.ForbiddenError @@ -428,13 +461,19 @@ service: publish: path: /sites/{site_id}/publish method: POST - auth: true + auth: + - OAuth2: + - sites:write docs: > - Publishes a site to one or more more domains. + Publishes a site to one or more more domains. + + To publish to a specific custom domain, use the domain IDs from the [Get + Custom Domains](/data/reference/sites/get-custom-domain) endpoint. - This endpoint has a limit of - one successful publish queue per minute. + + This endpoint has a + specific rate limit of one successful publish queue per minute. Required scope | `sites:write` @@ -460,6 +499,7 @@ service: response: docs: Request accepted type: SitesPublishResponse + status-code: 202 errors: - root.BadRequestError - root.UnauthorizedError @@ -467,9 +507,14 @@ service: - root.NotFoundError - root.TooManyRequestsError examples: - - path-parameters: + - name: DomainIDs + path-parameters: site_id: 580e63e98c9a982ac9b8b741 - request: {} + request: + customDomains: + - 660c6449dd97ebc7346ac629 + - 660c6449dd97ebc7346ac62f + publishToWebflowSubdomain: false response: body: customDomains: @@ -493,3 +538,21 @@ types: default: false source: openapi: ../../../openapi/referenced-specs/v2.yml +webhooks: + site_publish: + audiences: [] + method: POST + display-name: Site Publish + headers: {} + payload: root.SitePublish + examples: + - payload: + triggerType: site_publish + payload: + siteId: 62749158efef318abc8d5a0f + publishedOn: '2024-07-26T16:43:20Z' + domains: + - heartofgold.webflow.io + publishedBy: + displayName: Zaphod BeebleBrox + docs: Information about a site that was published diff --git a/.mock/definition/sites/activityLogs.yml b/.mock/definition/sites/activityLogs.yml index 1468f52..01f30f9 100644 --- a/.mock/definition/sites/activityLogs.yml +++ b/.mock/definition/sites/activityLogs.yml @@ -7,10 +7,18 @@ service: list: path: /sites/{site_id}/activity_logs method: GET - auth: true - docs: >- - Retrieve Activity Logs for a specific Site. Requires Site to be on an - Enterprise plan.

Required scope | `site_activity:read` + auth: + - OAuth2: + - site_activity:read + docs: > + Retrieve Activity Logs for a specific Site. + + + This endpoint requires an Enterprise + workspace. + + + Required scope: `site_activity:read` source: openapi: ../../../openapi/referenced-specs/v2.yml path-parameters: @@ -22,16 +30,17 @@ service: name: ActivityLogsListRequest query-parameters: limit: - type: optional + type: optional docs: 'Maximum number of records to be returned (max limit: 100)' offset: - type: optional + type: optional docs: >- Offset used for pagination if the results have more than limit records response: docs: A list of site activity logs type: root.SiteActivityLogResponse + status-code: 200 errors: - root.ForbiddenError - root.NotFoundError @@ -40,6 +49,9 @@ service: examples: - path-parameters: site_id: 580e63e98c9a982ac9b8b741 + query-parameters: + limit: 1 + offset: 1 response: body: items: diff --git a/.mock/definition/sites/comments.yml b/.mock/definition/sites/comments.yml new file mode 100644 index 0000000..3885152 --- /dev/null +++ b/.mock/definition/sites/comments.yml @@ -0,0 +1,352 @@ +types: + CommentsListCommentThreadsRequestSortBy: + enum: + - createdOn + - lastUpdated + source: + openapi: ../../../openapi/referenced-specs/v2.yml + CommentsListCommentThreadsRequestSortOrder: + enum: + - asc + - desc + source: + openapi: ../../../openapi/referenced-specs/v2.yml + CommentsGetCommentThreadRequestSortBy: + enum: + - createdOn + - lastUpdated + source: + openapi: ../../../openapi/referenced-specs/v2.yml + CommentsGetCommentThreadRequestSortOrder: + enum: + - asc + - desc + source: + openapi: ../../../openapi/referenced-specs/v2.yml + CommentsListCommentRepliesRequestSortBy: + enum: + - createdOn + - lastUpdated + source: + openapi: ../../../openapi/referenced-specs/v2.yml + CommentsListCommentRepliesRequestSortOrder: + enum: + - asc + - desc + source: + openapi: ../../../openapi/referenced-specs/v2.yml +imports: + root: ../__package__.yml +service: + auth: false + base-path: '' + endpoints: + list-comment-threads: + path: /sites/{site_id}/comments + method: GET + auth: + - OAuth2: + - comments:read + docs: | + List all comment threads for a site. + + + There may be a delay of up to 5 minutes before new comments appear in the system. + + + Required scope | `comments:read` + source: + openapi: ../../../openapi/referenced-specs/v2.yml + path-parameters: + site_id: + type: string + docs: Unique identifier for a Site + display-name: List Comment Threads + request: + name: CommentsListCommentThreadsRequest + query-parameters: + localeId: + type: optional + docs: > + Unique identifier for a specific Locale. + + + [Lear more about + localization.](/data/v2.0.0/docs/working-with-localization) + offset: + type: optional + docs: >- + Offset used for pagination if the results have more than limit + records + limit: + type: optional + docs: 'Maximum number of records to be returned (max limit: 100)' + sortBy: + type: optional + docs: >- + Sort results by the provided value. Only allowed when sortOrder is + provided. + sortOrder: + type: optional + docs: Sorts the results by asc or desc + response: + docs: Request was successful + type: root.CommentThreadList + status-code: 200 + errors: + - root.BadRequestError + - root.UnauthorizedError + - root.NotFoundError + - root.TooManyRequestsError + - root.InternalServerError + examples: + - path-parameters: + site_id: 580e63e98c9a982ac9b8b741 + query-parameters: + localeId: 65427cf400e02b306eaa04a0 + offset: 1 + limit: 1 + sortBy: createdOn + sortOrder: asc + response: + body: + comments: + - id: 679d2ddb5196117ad04d1ffa + siteId: 679826b3b20b045e176bc4b5 + pageId: 679826b3b20b045e176bc4bc + localeId: 67993753d910db250db64b3e + itemId: 580e64008c9a982ac9b8b754 + breakpoint: main + url: >- + https://webflow.com/design/site-slug-4ec832?workflow=comment&commentId=679d2ddb5196117ad04d1ff8&pageId=679826b3b20b045e176bc4bc + content: 'Let''s go to the pub! [[6287ec36a841b25637c663df]] ' + isResolved: false + author: + userId: 6287ec36a841b25637c663df + email: ford.prefect@heartofgold.spaceship + name: Ford Prefect + mentionedUsers: + - userId: 6287ec36a841b25637c663df + email: arthur.dent@heartofgold.spaceship + name: Arthur Dent + createdOn: '2025-01-31T20:08:59.759Z' + lastUpdated: '2025-01-31T20:08:59.759Z' + - id: 679d2ddb5196117ad04d1ffc + siteId: 679826b3b20b045e176bc4b5 + pageId: 679826b3b20b045e176bc4bc + localeId: 67993753d910db250db64b3e + itemId: 580e64008c9a982ac9b8b754 + breakpoint: main + url: >- + https://webflow.com/design/site-slug-4ec832?workflow=comment&commentId=679d2ddb5196117ad04d1ff8&pageId=679826b3b20b045e176bc4bc + content: >- + You have five minutes left to drink it + [[6287ec36a841b25637c663df]] + isResolved: false + author: + userId: 6287ec36a841b25637c663df + email: ford.prefect@heartofgold.spaceship + name: Ford Prefect + mentionedUsers: + - userId: 6287ec36a841b25637c663df + email: arthur.dent@heartofgold.spaceship + name: Arthur Dent + createdOn: '2025-01-31T20:08:59.759Z' + lastUpdated: '2025-01-31T20:08:59.759Z' + pagination: + limit: 2 + offset: 0 + total: 2 + get-comment-thread: + path: /sites/{site_id}/comments/{comment_thread_id} + method: GET + auth: + - OAuth2: + - comments:read + docs: | + Get details of a specific comment thread. + + + There may be a delay of up to 5 minutes before new comments appear in the system. + + + Required scope | `comments:read` + source: + openapi: ../../../openapi/referenced-specs/v2.yml + path-parameters: + site_id: + type: string + docs: Unique identifier for a Site + comment_thread_id: + type: string + docs: Unique identifier for a Comment Thread + display-name: Get Comment Thread + request: + name: CommentsGetCommentThreadRequest + query-parameters: + localeId: + type: optional + docs: > + Unique identifier for a specific Locale. + + + [Lear more about + localization.](/data/v2.0.0/docs/working-with-localization) + offset: + type: optional + docs: >- + Offset used for pagination if the results have more than limit + records + limit: + type: optional + docs: 'Maximum number of records to be returned (max limit: 100)' + sortBy: + type: optional + docs: >- + Sort results by the provided value. Only allowed when sortOrder is + provided. + sortOrder: + type: optional + docs: Sorts the results by asc or desc + response: + docs: Request was successful + type: root.CommentThread + status-code: 200 + errors: + - root.BadRequestError + - root.UnauthorizedError + - root.NotFoundError + - root.TooManyRequestsError + - root.InternalServerError + examples: + - path-parameters: + site_id: 580e63e98c9a982ac9b8b741 + comment_thread_id: 580e63e98c9a982ac9b8b741 + query-parameters: + localeId: 65427cf400e02b306eaa04a0 + offset: 1 + limit: 1 + sortBy: createdOn + sortOrder: asc + response: + body: + id: 580e64008c9a982ac9b8b754 + siteId: 580e64008c9a982ac9b8b754 + pageId: 580e64008c9a982ac9b8b754 + localeId: 580e64008c9a982ac9b8b754 + itemId: 580e64008c9a982ac9b8b754 + breakpoint: main + url: >- + https://webflow.com/design/site-slug-4ec832?workflow=comment&commentId=679d2ddb5196117ad04d1ff8&pageId=679826b3b20b045e176bc4bc + content: This is a comment reply + isResolved: true + author: + userId: userId + email: email + name: name + mentionedUsers: + - userId: 6287ec36a841b25637c663df + email: arthur.dent@heartofgold.spaceship + name: Arthur Dent + createdOn: '2023-03-17T18:47:35.560Z' + lastUpdated: '2023-03-17T18:47:35.560Z' + list-comment-replies: + path: /sites/{site_id}/comments/{comment_thread_id}/replies + method: GET + auth: + - OAuth2: + - comments:read + docs: | + List all replies to a specific comment thread. + + + There may be a delay of up to 5 minutes before new comments appear in the system. + + + Required scope | `comments:read` + source: + openapi: ../../../openapi/referenced-specs/v2.yml + path-parameters: + site_id: + type: string + docs: Unique identifier for a Site + comment_thread_id: + type: string + docs: Unique identifier for a Comment Thread + display-name: List Comment Replies + request: + name: CommentsListCommentRepliesRequest + query-parameters: + localeId: + type: optional + docs: > + Unique identifier for a specific Locale. + + + [Lear more about + localization.](/data/v2.0.0/docs/working-with-localization) + offset: + type: optional + docs: >- + Offset used for pagination if the results have more than limit + records + limit: + type: optional + docs: 'Maximum number of records to be returned (max limit: 100)' + sortBy: + type: optional + docs: >- + Sort results by the provided value. Only allowed when sortOrder is + provided. + sortOrder: + type: optional + docs: Sorts the results by asc or desc + response: + docs: Request was successful + type: root.CommentReplyList + status-code: 200 + errors: + - root.BadRequestError + - root.UnauthorizedError + - root.NotFoundError + - root.TooManyRequestsError + - root.InternalServerError + examples: + - path-parameters: + site_id: 580e63e98c9a982ac9b8b741 + comment_thread_id: 580e63e98c9a982ac9b8b741 + query-parameters: + localeId: 65427cf400e02b306eaa04a0 + offset: 1 + limit: 1 + sortBy: createdOn + sortOrder: asc + response: + body: + comments: + - id: 679d2ddb5196117ad04d1ffa + commentId: 679d2ddb5196117ad04d1ff8 + siteId: 679826b3b20b045e176bc4b5 + pageId: 679826b3b20b045e176bc4bc + localeId: 67993753d910db250db64b3e + breakpoint: main + content: >- + This comment mentions another user + [[6287ec36a841b25637c663df]] + isResolved: false + author: + id: id + email: email + name: name + mentionedUsers: + - id: id + email: arthur.dent@example.com + name: Arthur Dent + lastUpdated: '2025-01-31T20:08:59.759Z' + createdOn: '2025-01-31T20:08:59.759Z' + pagination: + limit: 2 + offset: 0 + total: 1 + source: + openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/sites/forms.yml b/.mock/definition/sites/forms.yml new file mode 100644 index 0000000..27e1e1d --- /dev/null +++ b/.mock/definition/sites/forms.yml @@ -0,0 +1,316 @@ +imports: + root: ../__package__.yml +service: + auth: false + base-path: '' + endpoints: + list-submissions-by-site: + path: /sites/{site_id}/form_submissions + method: GET + auth: + - OAuth2: + - forms:read + docs: > + List all form submissions for a given site with the ability to filter + submissions by a centralized `elementId`. + + + Add `elementId` when you want to filter form submissions to a specific + form in a site. You can get the `elementId` from the [List forms + endpoint](/data/reference/forms/forms/list) (displayed as + `formElementId` in the response). + + + + + When a form is used in a Webflow component definition, each instance of + the component will yield a unique form. Adding the `elementId` in this + request ensures this API response includes all submissions from that + core form, wherever that form is used in instantiated components. + + + + + Use the [List Form Submissions + endpoint](/data/reference/forms/form-submissions/list-submissions) to + list form submissions for a given form ID. + + + Required scope | `forms:read` + source: + openapi: ../../../openapi/referenced-specs/v2.yml + path-parameters: + site_id: + type: string + docs: Unique identifier for a Site + display-name: List Form Submissions by Site + request: + name: FormsListSubmissionsBySiteRequest + query-parameters: + elementId: + type: optional + docs: Identifier for an element + offset: + type: optional + docs: >- + Offset used for pagination if the results have more than limit + records + limit: + type: optional + docs: 'Maximum number of records to be returned (max limit: 100)' + response: + docs: Request was successful + type: root.FormSubmissionList + status-code: 200 + errors: + - root.BadRequestError + - root.UnauthorizedError + - root.ForbiddenError + - root.NotFoundError + - root.TooManyRequestsError + - root.InternalServerError + examples: + - path-parameters: + site_id: 580e63e98c9a982ac9b8b741 + query-parameters: + elementId: 18259716-3e5a-646a-5f41-5dc4b9405aa0 + offset: 1 + limit: 1 + response: + body: + formSubmissions: + - id: 6321ca84df3949bfc6752327 + displayName: Sample Form + siteId: 62749158efef318abc8d5a0f + workspaceId: 62749158efef318abc8d5a0f + dateSubmitted: '2022-09-14T12:35:16Z' + formResponse: + First Name: Arthur + Last Name: Dent + - id: 660d64fabf6e0a0d4edab981 + displayName: Sample Form + siteId: 62749158efef318abc8d5a0f + workspaceId: 62749158efef318abc8d5a0f + dateSubmitted: '2022-09-14T12:35:16Z' + formResponse: + First Name: Ford + Last Name: Prefect + pagination: + limit: 25 + offset: 0 + total: 2 + list-submissions: + path: /sites/{site_id}/forms/{form_id}/submissions + method: GET + auth: + - OAuth2: + - forms:read + docs: > + List form submissions for a given form ID within a specific site. + + + Use the [List Form Submissions by Site + endpoint](/data/reference/forms/form-submissions/list-submissions-by-site) + to list form submissions for a given site with the ability to filter by + a `formElementId`. + + + Required scope | `forms:read` + source: + openapi: ../../../openapi/referenced-specs/v2.yml + path-parameters: + site_id: + type: string + docs: Unique identifier for a Site + form_id: + type: string + docs: Unique identifier for a Form + display-name: List Form Submissions + request: + name: FormsListSubmissionsRequest + query-parameters: + offset: + type: optional + docs: >- + Offset used for pagination if the results have more than limit + records + limit: + type: optional + docs: 'Maximum number of records to be returned (max limit: 100)' + response: + docs: Request was successful + type: root.FormSubmissionList + status-code: 200 + errors: + - root.BadRequestError + - root.UnauthorizedError + - root.ForbiddenError + - root.NotFoundError + - root.TooManyRequestsError + - root.InternalServerError + examples: + - path-parameters: + site_id: 580e63e98c9a982ac9b8b741 + form_id: 580e63e98c9a982ac9b8b741 + query-parameters: + offset: 1 + limit: 1 + response: + body: + formSubmissions: + - id: 6321ca84df3949bfc6752327 + displayName: Sample Form + siteId: 62749158efef318abc8d5a0f + workspaceId: 62749158efef318abc8d5a0f + dateSubmitted: '2022-09-14T12:35:16Z' + formResponse: + First Name: Arthur + Last Name: Dent + - id: 660d64fabf6e0a0d4edab981 + displayName: Sample Form + siteId: 62749158efef318abc8d5a0f + workspaceId: 62749158efef318abc8d5a0f + dateSubmitted: '2022-09-14T12:35:16Z' + formResponse: + First Name: Ford + Last Name: Prefect + pagination: + limit: 25 + offset: 0 + total: 2 + get-submission: + path: /sites/{site_id}/form_submissions/{form_submission_id} + method: GET + auth: + - OAuth2: + - forms:read + docs: | + Get information about a form submission within a specific site. + + Required scope | `forms:read` + source: + openapi: ../../../openapi/referenced-specs/v2.yml + path-parameters: + site_id: + type: string + docs: Unique identifier for a Site + form_submission_id: + type: string + docs: Unique identifier for a Form Submission + display-name: Get Form Submission by Site + response: + docs: Request was successful + type: root.FormSubmission + status-code: 200 + errors: + - root.BadRequestError + - root.UnauthorizedError + - root.ForbiddenError + - root.NotFoundError + - root.TooManyRequestsError + - root.InternalServerError + examples: + - path-parameters: + site_id: 580e63e98c9a982ac9b8b741 + form_submission_id: 580e63e98c9a982ac9b8b741 + response: + body: + id: 6321ca84df3949bfc6752327 + displayName: Sample Form + siteId: 62749158efef318abc8d5a0f + workspaceId: 62749158efef318abc8d5a0f + dateSubmitted: '2022-09-14T12:35:16Z' + formResponse: + First Name: Arthur + Last Name: Dent + delete-submission: + path: /sites/{site_id}/form_submissions/{form_submission_id} + method: DELETE + auth: + - OAuth2: + - forms:write + docs: | + Delete a form submission within a specific site. + + Required scope | `forms:write` + source: + openapi: ../../../openapi/referenced-specs/v2.yml + path-parameters: + site_id: + type: string + docs: Unique identifier for a Site + form_submission_id: + type: string + docs: Unique identifier for a Form Submission + display-name: Delete Form Submission by Site + errors: + - root.BadRequestError + - root.UnauthorizedError + - root.ForbiddenError + - root.NotFoundError + - root.ConflictError + - root.TooManyRequestsError + - root.InternalServerError + examples: + - path-parameters: + site_id: 580e63e98c9a982ac9b8b741 + form_submission_id: 580e63e98c9a982ac9b8b741 + update-submission: + path: /sites/{site_id}/form_submissions/{form_submission_id} + method: PATCH + auth: + - OAuth2: + - forms:write + docs: | + Update hidden fields on a form submission within a specific site. + + Required scope | `forms:write` + source: + openapi: ../../../openapi/referenced-specs/v2.yml + path-parameters: + site_id: + type: string + docs: Unique identifier for a Site + form_submission_id: + type: string + docs: Unique identifier for a Form Submission + display-name: Modify Form Submission by Site + request: + name: FormsUpdateSubmissionRequest + body: + properties: + formSubmissionData: + type: optional> + docs: >- + An existing **hidden field** defined on the form schema, and the + corresponding value to set + content-type: application/json + response: + docs: Request was successful + type: root.FormSubmission + status-code: 200 + errors: + - root.BadRequestError + - root.UnauthorizedError + - root.ForbiddenError + - root.NotFoundError + - root.ConflictError + - root.TooManyRequestsError + - root.InternalServerError + examples: + - path-parameters: + site_id: 580e63e98c9a982ac9b8b741 + form_submission_id: 580e63e98c9a982ac9b8b741 + request: {} + response: + body: + id: 6321ca84df3949bfc6752327 + displayName: Sample Form + siteId: 62749158efef318abc8d5a0f + workspaceId: 62749158efef318abc8d5a0f + dateSubmitted: '2022-09-14T12:35:16Z' + formResponse: + First Name: Arthur + Last Name: Dent + source: + openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/sites/plans.yml b/.mock/definition/sites/plans.yml index ae9de6d..4f662bc 100644 --- a/.mock/definition/sites/plans.yml +++ b/.mock/definition/sites/plans.yml @@ -7,10 +7,17 @@ service: get-site-plan: path: /sites/{site_id}/plan method: GET - auth: true - docs: | + auth: + - OAuth2: + - sites:read + docs: > Get site plan details for the specified Site. + + This endpoint requires an Enterprise + workspace. + + Required scope | `sites:read` source: openapi: ../../../openapi/referenced-specs/v2.yml @@ -22,6 +29,7 @@ service: response: docs: Request was successful type: root.SitePlan + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError diff --git a/.mock/definition/sites/redirects.yml b/.mock/definition/sites/redirects.yml index b104d86..806117c 100644 --- a/.mock/definition/sites/redirects.yml +++ b/.mock/definition/sites/redirects.yml @@ -7,15 +7,20 @@ service: list: path: /sites/{site_id}/redirects method: GET - auth: true + auth: + - OAuth2: + - sites:read docs: > - Fetch a list of all URL redirect rules configured for a specific site. + Fetch a list of all 301 redirect rules configured for a specific site. Use this endpoint to review, audit, or manage the redirection rules that control how traffic is rerouted on your site. + This endpoint requires an Enterprise + workspace. + Required scope: `sites:read` source: @@ -24,10 +29,11 @@ service: site_id: type: string docs: Unique identifier for a Site - display-name: Get URL redirects + display-name: Get 301 redirects response: docs: Request was successful type: root.Redirects + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -53,9 +59,11 @@ service: create: path: /sites/{site_id}/redirects method: POST - auth: true + auth: + - OAuth2: + - sites:write docs: > - Add a new URL redirection rule to a site. + Add a new 301 redirection rule to a site. This endpoint allows you to define a source path (`fromUrl`) and its @@ -64,6 +72,10 @@ service: restructuring URLs, or handling outdated links. + This endpoint requires an Enterprise + workspace. + + Required scope: `sites:write` source: openapi: ../../../openapi/referenced-specs/v2.yml @@ -71,13 +83,14 @@ service: site_id: type: string docs: Unique identifier for a Site - display-name: Create a URL redirect + display-name: Create a 301 redirect request: body: root.Redirect content-type: application/json response: docs: Request was successful type: root.Redirect + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -99,14 +112,22 @@ service: delete: path: /sites/{site_id}/redirects/{redirect_id} method: DELETE - auth: true + auth: + - OAuth2: + - sites:write docs: > - Remove a URL redirection rule from a site. + Remove a 301 redirection rule from a site. + This is useful for cleaning up outdated or unnecessary redirects, ensuring that your site's routing behavior remains efficient and up-to-date. + + This endpoint requires an Enterprise + workspace. + + Required scope: `sites:write` source: openapi: ../../../openapi/referenced-specs/v2.yml @@ -117,10 +138,11 @@ service: redirect_id: type: string docs: Unique identifier site rediect - display-name: Delete URL redirects + display-name: Delete 301 redirects response: docs: Request was successful type: root.Redirects + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -147,9 +169,17 @@ service: update: path: /sites/{site_id}/redirects/{redirect_id} method: PATCH - auth: true - docs: | - Update a URL redirection rule from a site. + auth: + - OAuth2: + - sites:write + docs: > + Update a 301 redirection rule from a site. + + + This endpoint requires an Enterprise + workspace. + + Required scope: `sites:write` source: openapi: ../../../openapi/referenced-specs/v2.yml @@ -160,13 +190,14 @@ service: redirect_id: type: string docs: Unique identifier site rediect - display-name: Update URL redirect + display-name: Update 301 redirect request: body: root.Redirect content-type: application/json response: docs: Request was successful type: root.Redirect + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError diff --git a/.mock/definition/sites/robotsTxt.yml b/.mock/definition/sites/robotsTxt.yml new file mode 100644 index 0000000..1aaf6cf --- /dev/null +++ b/.mock/definition/sites/robotsTxt.yml @@ -0,0 +1,229 @@ +imports: + root: ../__package__.yml +service: + auth: false + base-path: '' + endpoints: + get: + path: /sites/{site_id}/robots_txt + method: GET + auth: + - OAuth2: + - site_config:read + docs: > + Retrieve the robots.txt configuration for various user agents. + + + This endpoint requires an Enterprise + workspace. + + + Required scope: `site_config:read` + source: + openapi: ../../../openapi/referenced-specs/v2.yml + path-parameters: + site_id: + type: string + docs: Unique identifier for a Site + display-name: Get robots.txt + response: + docs: Request was successful + type: root.Robots + status-code: 200 + errors: + - root.BadRequestError + - root.UnauthorizedError + - root.NotFoundError + - root.TooManyRequestsError + - root.InternalServerError + examples: + - path-parameters: + site_id: 580e63e98c9a982ac9b8b741 + response: + body: + rules: + - userAgent: googlebot + allows: + - /public + disallows: + - /vogon-poetry + - /total-perspective-vortex + sitemap: https://heartofgold.ship/sitemap.xml + put: + path: /sites/{site_id}/robots_txt + method: PUT + auth: + - OAuth2: + - site_config:write + docs: > + Replace the `robots.txt` configuration for various user agents. + + + This endpoint requires an Enterprise + workspace. + + + Required scope | `site_config:write` + source: + openapi: ../../../openapi/referenced-specs/v2.yml + path-parameters: + site_id: + type: string + docs: Unique identifier for a Site + display-name: Replace robots.txt + request: + body: root.Robots + content-type: application/json + response: + docs: Request was successful + type: root.Robots + status-code: 200 + errors: + - root.BadRequestError + - root.UnauthorizedError + - root.NotFoundError + - root.TooManyRequestsError + - root.InternalServerError + examples: + - path-parameters: + site_id: 580e63e98c9a982ac9b8b741 + request: + rules: + - userAgent: googlebot + allows: + - /public + disallows: + - /vogon-poetry + - /total-perspective-vortex + sitemap: https://heartofgold.ship/sitemap.xml + response: + body: + rules: + - userAgent: googlebot + allows: + - /public + disallows: + - /vogon-poetry + - /total-perspective-vortex + sitemap: https://heartofgold.ship/sitemap.xml + delete: + path: /sites/{site_id}/robots_txt + method: DELETE + auth: + - OAuth2: + - site_config:write + docs: > + Remove specific rules for a user-agent in your `robots.txt` file. To + delete all rules for a user-agent, provide an empty rule set. This will + remove the user-agent's entry entirely, leaving it subject to your + site's default crawling behavior. + + + **Note:** Deleting a user-agent with no rules will make the user-agent's + access unrestricted unless other directives apply. + + + This endpoint requires an Enterprise + workspace. + + + Required scope: `site_config:write` + source: + openapi: ../../../openapi/referenced-specs/v2.yml + path-parameters: + site_id: + type: string + docs: Unique identifier for a Site + display-name: Delete robots.txt + request: + body: root.Robots + content-type: application/json + response: + docs: Request was successful + type: root.Robots + status-code: 200 + errors: + - root.BadRequestError + - root.UnauthorizedError + - root.NotFoundError + - root.TooManyRequestsError + - root.InternalServerError + examples: + - path-parameters: + site_id: 580e63e98c9a982ac9b8b741 + request: + rules: + - userAgent: '*' + allows: + - /public + disallows: + - /bubbles + response: + body: + rules: + - userAgent: googlebot + allows: + - /public + disallows: + - /vogon-poetry + - /total-perspective-vortex + sitemap: https://heartofgold.ship/sitemap.xml + patch: + path: /sites/{site_id}/robots_txt + method: PATCH + auth: + - OAuth2: + - site_config:write + docs: > + Update the `robots.txt` configuration for various user agents. + + + This endpoint requires an Enterprise + workspace. + + + Required scope | `site_config:write` + source: + openapi: ../../../openapi/referenced-specs/v2.yml + path-parameters: + site_id: + type: string + docs: Unique identifier for a Site + display-name: Update robots.txt + request: + body: root.Robots + content-type: application/json + response: + docs: Request was successful + type: root.Robots + status-code: 200 + errors: + - root.BadRequestError + - root.UnauthorizedError + - root.NotFoundError + - root.TooManyRequestsError + - root.InternalServerError + examples: + - path-parameters: + site_id: 580e63e98c9a982ac9b8b741 + request: + rules: + - userAgent: googlebot + allows: + - /public + disallows: + - /vogon-poetry + - /total-perspective-vortex + sitemap: https://heartofgold.ship/sitemap.xml + response: + body: + rules: + - userAgent: googlebot + allows: + - /public + disallows: + - /vogon-poetry + - /total-perspective-vortex + sitemap: https://heartofgold.ship/sitemap.xml + source: + openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/sites/scripts.yml b/.mock/definition/sites/scripts.yml index 92ad0e4..6762c85 100644 --- a/.mock/definition/sites/scripts.yml +++ b/.mock/definition/sites/scripts.yml @@ -7,14 +7,15 @@ service: get-custom-code: path: /sites/{site_id}/custom_code method: GET - auth: true - docs: > - Get all registered scripts that have been applied to a specific Site. - - - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). + auth: + - OAuth2: + - custom_code:read + docs: | + Get all scripts applied to a site by the App. + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:read` source: @@ -27,6 +28,7 @@ service: response: docs: Request was successful type: root.ScriptApplyList + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -54,22 +56,20 @@ service: upsert-custom-code: path: /sites/{site_id}/custom_code method: PUT - auth: true + auth: + - OAuth2: + - custom_code:write docs: > - Add a registered script to a Site. - - - In order to use the Custom Code APIs for Sites and Pages, Custom Code - Scripts must first be registered + Apply registered scripts to a site. If you have multiple scripts your + App needs to apply or maintain on a site, ensure they are always + included in the request body for this endpoint. To remove individual + scripts, simply call this endpoint without the script in the request + body. - to a Site via the `registered_scripts` endpoints, and then applied to a - Site or Page using the appropriate - `custom_code` endpoints. - - - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` @@ -86,6 +86,7 @@ service: response: docs: Request was successful type: root.ScriptApplyList + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -123,13 +124,22 @@ service: delete-custom-code: path: /sites/{site_id}/custom_code method: DELETE - auth: true + auth: + - OAuth2: + - custom_code:write docs: > - Delete the custom code block that an app created for a Site + Remove all scripts from a site applied by the App. This endpoint will + not remove scripts from the site's registered scripts. + + + To remove individual scripts applied by the App, use the [Add/Update + Custom + Code](/data/reference/custom-code/custom-code-sites/upsert-custom-code) + endpoint. - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). + Access to this endpoint requires a bearer token obtained from an + [OAuth Code Grant Flow](/data/reference/oauth-app). Required scope | `custom_code:write` @@ -152,13 +162,19 @@ service: list-custom-code-blocks: path: /sites/{site_id}/custom_code/blocks method: GET - auth: true + auth: + - OAuth2: + - custom_code:read docs: > - Get all instances of Custom Code applied to a Site or Pages. + Get a list of scripts that have been applied to a site and/or individual + pages. - Access to this endpoint requires a bearer token from a [Data - Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. + + See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:read` @@ -173,16 +189,17 @@ service: name: ScriptsListCustomCodeBlocksRequest query-parameters: offset: - type: optional + type: optional docs: >- Offset used for pagination if the results have more than limit records limit: - type: optional + type: optional docs: 'Maximum number of records to be returned (max limit: 100)' response: docs: Request was successful type: root.ListCustomCodeBlocks + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -192,6 +209,9 @@ service: examples: - path-parameters: site_id: 580e63e98c9a982ac9b8b741 + query-parameters: + offset: 1 + limit: 1 response: body: blocks: diff --git a/.mock/definition/sites/wellKnown.yml b/.mock/definition/sites/wellKnown.yml new file mode 100644 index 0000000..10ef3e0 --- /dev/null +++ b/.mock/definition/sites/wellKnown.yml @@ -0,0 +1,130 @@ +types: + WellKnownFileContentType: + enum: + - value: application/json + name: ApplicationJson + - value: text/plain + name: TextPlain + docs: The content type of the file. Defaults to application/json + default: application/json + inline: true + source: + openapi: ../../../openapi/referenced-specs/v2.yml +imports: + root: ../__package__.yml +service: + auth: false + base-path: '' + endpoints: + put: + path: /sites/{site_id}/well_known + method: PUT + auth: + - OAuth2: + - site_config:write + docs: > + Upload a supported well-known file to a site. + + + The current restrictions on well-known files are as follows: + - Each file must be smaller than 100kb + - Less than 30 total files + - Have one of the following file extensions (or no extension): `.txt`, `.json`, `.noext` + + + `.noext` is a special file extension that removes other extensions. For example, `apple-app-site-association.noext.txt` will be uploaded as `apple-app-site-association`. Use this extension for tools that have trouble uploading extensionless files. + + + This endpoint requires an Enterprise + workspace. + + + Required scope: `site_config:write` + source: + openapi: ../../../openapi/referenced-specs/v2.yml + path-parameters: + site_id: + type: string + docs: Unique identifier for a Site + display-name: Set a well-known file + request: + name: WellKnownFile + body: + properties: + fileName: + type: string + docs: The name of the file + fileData: + type: string + docs: The contents of the file + contentType: + type: optional + docs: The content type of the file. Defaults to application/json + default: application/json + content-type: application/json + errors: + - root.BadRequestError + - root.UnauthorizedError + - root.NotFoundError + - root.TooManyRequestsError + - root.InternalServerError + examples: + - path-parameters: + site_id: 580e63e98c9a982ac9b8b741 + request: + fileName: apple-app-site-association.txt + fileData: | + { + "applinks": { + "apps": [], + "details": [ + { + "appID": "ABCDE12345.com.example.app", + "paths": [ "/*", "/some/path/*" ] + } + ] + } + } + contentType: application/json + delete: + path: /sites/{site_id}/well_known + method: DELETE + auth: + - OAuth2: + - site_config:write + docs: > + Delete existing well-known files from a site. + + + This endpoint requires an Enterprise + workspace. + + + Required scope: `site_config:write` + source: + openapi: ../../../openapi/referenced-specs/v2.yml + path-parameters: + site_id: + type: string + docs: Unique identifier for a Site + display-name: Delete a well-known file + request: + name: WellKnownDeleteRequest + body: + properties: + fileNames: + type: optional> + docs: A list of file names to delete + content-type: application/json + errors: + - root.BadRequestError + - root.UnauthorizedError + - root.NotFoundError + - root.TooManyRequestsError + - root.InternalServerError + examples: + - path-parameters: + site_id: 580e63e98c9a982ac9b8b741 + request: {} + source: + openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/token.yml b/.mock/definition/token.yml index 033c5c3..4b0e365 100644 --- a/.mock/definition/token.yml +++ b/.mock/definition/token.yml @@ -7,7 +7,9 @@ service: authorized-by: path: /token/authorized_by method: GET - auth: true + auth: + - OAuth2: + - authorized_user:read docs: | Information about the Authorized User @@ -18,6 +20,7 @@ service: response: docs: Request was successful type: root.AuthorizedUser + status-code: 200 errors: - root.UnauthorizedError - root.ForbiddenError @@ -31,7 +34,6 @@ service: introspect: path: /token/introspect method: GET - auth: true docs: > Information about the authorization token @@ -44,6 +46,7 @@ service: response: docs: Request was successful type: root.Authorization + status-code: 200 errors: - root.UnauthorizedError examples: diff --git a/.mock/definition/users.yml b/.mock/definition/users.yml deleted file mode 100644 index 19a17cc..0000000 --- a/.mock/definition/users.yml +++ /dev/null @@ -1,392 +0,0 @@ -types: - UsersListRequestSort: - enum: - - value: CreatedOn - name: CreatedOnAscending - docs: Sorts users in ascending order based on their created date - - value: '-CreatedOn' - name: CreatedOnDescending - docs: Sorts users in descending order based on their created date - - value: Email - name: EmailAscending - docs: Sorts users in ascending order based on their email - - value: '-Email' - name: EmailDescending - docs: Sorts users in descending order based on their email - - value: Status - name: StatusAscending - docs: Sorts users in ascending order based on their status - - value: '-Status' - name: StatusDescending - docs: Sorts users in descending order based on their status - - value: LastLogin - name: LastLoginAscending - docs: Sorts users in ascending order based on their last login date - - value: '-LastLogin' - name: LastLoginDescending - docs: Sorts users in descending order based on their last login date - - value: UpdatedOn - name: UpdatedOnAscending - docs: Sorts users in ascending order based on their update date - - value: '-UpdatedOn' - name: UpdatedOnDescending - docs: Sorts users in descending order based on their update date - source: - openapi: ../../../openapi/referenced-specs/v2.yml - UsersUpdateRequestData: - properties: - name: - type: optional - docs: | - The name of the user - accept-privacy: - type: optional - docs: | - Boolean indicating if the user has accepted the privacy policy - accept-communications: - type: optional - docs: | - Boolean indicating if the user has accepted to receive communications - source: - openapi: ../../../openapi/referenced-specs/v2.yml - inline: true -imports: - root: __package__.yml -service: - auth: false - base-path: '' - endpoints: - list: - path: /sites/{site_id}/users - method: GET - auth: true - docs: | - Get a list of users for a site - - Required scope | `users:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: List Users - request: - name: UsersListRequest - query-parameters: - offset: - type: optional - docs: >- - Offset used for pagination if the results have more than limit - records - limit: - type: optional - docs: 'Maximum number of records to be returned (max limit: 100)' - sort: - type: optional - docs: | - Sort string to use when ordering users - - Example(`CreatedOn`, `Email`, `Status`, `LastLogin`, `UpdatedOn`). - - Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`) - response: - docs: Request was successful - type: root.UserList - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - response: - body: - count: 5 - limit: 5 - offset: 0 - total: 201 - users: - - id: 6287ec36a841b25637c663df - isEmailVerified: false - lastUpdated: '2022-05-20T13:46:12Z' - invitedOn: '2016-10-24T19:41:29Z' - createdOn: '2022-05-20T13:46:12Z' - lastLogin: '2016-10-24T19:41:29Z' - status: unverified - accessGroups: - - slug: vogon-construction-crew - type: admin - - id: 6287ec36a841b25637c663f0 - isEmailVerified: false - lastUpdated: '2022-05-19T05:32:04Z' - invitedOn: '2016-10-24T19:41:29Z' - createdOn: '2022-05-19T05:32:04Z' - lastLogin: '2016-10-24T19:41:29Z' - status: unverified - accessGroups: - - slug: improbability-drive-test-subjects - type: admin - - id: 6287ec36a841b25637c663d9 - isEmailVerified: true - lastUpdated: '2022-05-17T03:34:06Z' - invitedOn: '2016-10-24T19:41:29Z' - createdOn: '2022-05-17T03:34:06Z' - lastLogin: '2016-10-24T19:41:29Z' - status: verified - accessGroups: - - slug: heart-of-gold-crew - type: admin - - id: 6287ec37a841b25637c6641b - isEmailVerified: false - lastUpdated: '2022-05-15T03:46:09Z' - invitedOn: '2016-10-24T19:41:29Z' - createdOn: '2022-05-15T03:46:09Z' - lastLogin: '2016-10-24T19:41:29Z' - status: unverified - accessGroups: - - slug: hitchhikers-guide-research-team - type: admin - - id: 6287ec37a841b25637c66449 - isEmailVerified: true - lastUpdated: '2022-05-15T02:55:38Z' - invitedOn: '2016-10-24T19:41:29Z' - createdOn: '2022-05-15T02:55:38Z' - lastLogin: '2016-10-24T19:41:29Z' - status: verified - accessGroups: - - slug: milliways-reservationists - type: admin - get: - path: /sites/{site_id}/users/{user_id} - method: GET - auth: true - docs: | - Get a User by ID - - Required scope | `users:read` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - user_id: - type: string - docs: Unique identifier for a User - display-name: Get User - response: - docs: Request was successful - type: root.User - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - user_id: 580e63e98c9a982ac9b8b741 - response: - body: - id: 6287ec36a841b25637c663df - isEmailVerified: true - lastUpdated: '2022-05-20T13:46:12Z' - invitedOn: '2022-05-20T13:46:12Z' - createdOn: '2022-05-20T13:46:12Z' - lastLogin: '2022-05-20T13:46:12Z' - status: verified - accessGroups: - - slug: webflowers - type: admin - data: - data: - name: name - email: email - accept-privacy: true - accept-communications: true - additionalProperties: additionalProperties - delete: - path: /sites/{site_id}/users/{user_id} - method: DELETE - auth: true - docs: | - Delete a User by ID - - Required scope | `users:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - user_id: - type: string - docs: Unique identifier for a User - display-name: Delete User - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - user_id: 580e63e98c9a982ac9b8b741 - update: - path: /sites/{site_id}/users/{user_id} - method: PATCH - auth: true - docs: | - Update a User by ID - - Required scope | `users:write` - - The email and password - fields cannot be updated using this endpoint - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - user_id: - type: string - docs: Unique identifier for a User - display-name: Update User - request: - name: UsersUpdateRequest - body: - properties: - data: optional - accessGroups: - type: optional> - docs: > - An array of access group slugs. Access groups are assigned to - the user as type `admin` and the user remains in the group until - removed. - content-type: application/json - response: - docs: Request was successful - type: root.User - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - user_id: 580e63e98c9a982ac9b8b741 - request: - data: - name: Some One - accept-privacy: false - accept-communications: false - accessGroups: - - webflowers - - platinum - - free-tier - response: - body: - id: 6287ec36a841b25637c663df - isEmailVerified: true - lastUpdated: '2022-05-20T13:46:12Z' - invitedOn: '2022-05-20T13:46:12Z' - createdOn: '2022-05-20T13:46:12Z' - lastLogin: '2022-05-20T13:46:12Z' - status: verified - accessGroups: - - slug: webflowers - type: admin - data: - data: - name: name - email: email - accept-privacy: true - accept-communications: true - additionalProperties: additionalProperties - invite: - path: /sites/{site_id}/users/invite - method: POST - auth: true - docs: > - Create and invite a user with an email address. - - - The user will be sent and invite via email, which they will need to - accept in order to join paid any paid access group. - - - Required scope | `users:write` - source: - openapi: ../../../openapi/referenced-specs/v2.yml - path-parameters: - site_id: - type: string - docs: Unique identifier for a Site - display-name: Create and Invite a User - request: - name: UsersInviteRequest - body: - properties: - email: - type: string - docs: Email address of user to send invite to - validation: - format: email - accessGroups: - type: optional> - docs: > - An array of access group slugs. Access groups are assigned to - the user as type `admin` and the user remains in the group until - removed. - content-type: application/json - response: - docs: Request was successful - type: root.User - errors: - - root.BadRequestError - - root.UnauthorizedError - - root.ForbiddenError - - root.NotFoundError - - root.ConflictError - - root.TooManyRequestsError - - root.InternalServerError - examples: - - path-parameters: - site_id: 580e63e98c9a982ac9b8b741 - request: - email: some.one@home.com - accessGroups: - - webflowers - response: - body: - id: 6287ec36a841b25637c663df - isEmailVerified: true - lastUpdated: '2022-05-20T13:46:12Z' - invitedOn: '2022-05-20T13:46:12Z' - createdOn: '2022-05-20T13:46:12Z' - lastLogin: '2022-05-20T13:46:12Z' - status: verified - accessGroups: - - slug: webflowers - type: admin - data: - data: - name: name - email: email - accept-privacy: true - accept-communications: true - additionalProperties: additionalProperties - source: - openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/definition/webhooks.yml b/.mock/definition/webhooks.yml index d40e3e4..46bbb02 100644 --- a/.mock/definition/webhooks.yml +++ b/.mock/definition/webhooks.yml @@ -7,7 +7,6 @@ service: list: path: /sites/{site_id}/webhooks method: GET - auth: true docs: | List all App-created Webhooks registered for a given site @@ -22,6 +21,7 @@ service: response: docs: Request was successful type: root.WebhookList + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -33,10 +33,6 @@ service: site_id: 580e63e98c9a982ac9b8b741 response: body: - pagination: - limit: 100 - offset: 0 - total: 100 webhooks: - id: 57ca0a9e418c504a6e1acbb6 triggerType: form_submission @@ -65,10 +61,13 @@ service: name: Email Form lastTriggered: '2023-02-08T23:59:28Z' createdOn: '2016-07-19T01:43:40Z' + pagination: + limit: 100 + offset: 0 + total: 100 create: path: /sites/{site_id}/webhooks method: POST - auth: true docs: > Create a new Webhook. @@ -93,6 +92,7 @@ service: response: docs: Request was successful type: root.Webhook + status-code: 201 errors: - root.BadRequestError - root.UnauthorizedError @@ -124,7 +124,6 @@ service: get: path: /webhooks/{webhook_id} method: GET - auth: true docs: | Get a specific Webhook instance @@ -139,6 +138,7 @@ service: response: docs: Request was successful type: root.Webhook + status-code: 200 errors: - root.BadRequestError - root.UnauthorizedError @@ -162,7 +162,6 @@ service: delete: path: /webhooks/{webhook_id} method: DELETE - auth: true docs: | Remove a Webhook diff --git a/.mock/definition/workspaces/auditLogs.yml b/.mock/definition/workspaces/auditLogs.yml new file mode 100644 index 0000000..57b604a --- /dev/null +++ b/.mock/definition/workspaces/auditLogs.yml @@ -0,0 +1,126 @@ +types: + AuditLogsGetWorkspaceAuditLogsRequestSortOrder: + enum: + - asc + - desc + source: + openapi: ../../../openapi/referenced-specs/v2.yml + AuditLogsGetWorkspaceAuditLogsRequestEventType: + enum: + - user_access + - custom_role + - workspace_membership + - site_membership + - workspace_invitation + - workspace_setting + source: + openapi: ../../../openapi/referenced-specs/v2.yml +imports: + root: ../__package__.yml +service: + auth: false + base-path: '' + endpoints: + get-workspace-audit_logs: + path: /workspaces/{workspace_id_or_slug}/audit_logs + method: GET + auth: + - OAuth2: + - workspace_activity:read + docs: > + Get audit logs for a workspace. + + + This endpoint + requires an Enterprise workspace and a workspace token with the + `workspace_activity:read` scope. Create a workspace token from your + workspace dashboard integrations page to use this endpoint. + + + Required scope | `workspace_activity:read` + source: + openapi: ../../../openapi/referenced-specs/v2.yml + path-parameters: + workspace_id_or_slug: + type: string + docs: Unique identifier or slug for a Workspace + display-name: Get Workspace Audit Logs + request: + name: AuditLogsGetWorkspaceAuditLogsRequest + query-parameters: + limit: + type: optional + docs: 'Maximum number of records to be returned (max limit: 100)' + offset: + type: optional + docs: >- + Offset used for pagination if the results have more than limit + records + sortOrder: + type: optional + docs: Sorts the results by asc or desc + eventType: + type: optional + docs: The event type to filter by + from: + type: optional + docs: The start date to filter by + to: + type: optional + docs: The end date to filter by + response: + docs: A list of workspace audit logs + type: root.WorkspaceAuditLogResponse + status-code: 200 + errors: + - root.UnauthorizedError + - root.ForbiddenError + - root.NotFoundError + - root.TooManyRequestsError + - root.InternalServerError + examples: + - path-parameters: + workspace_id_or_slug: hitchhikers-workspace + query-parameters: + limit: 1 + offset: 1 + sortOrder: asc + eventType: user_access + from: '2025-06-22T16:00:31Z' + to: '2025-07-22T16:00:31Z' + response: + body: + items: + - eventSubType: login + eventType: user_access + timestamp: '2025-04-29T20:30:06Z' + actor: + id: 6661ccb359b561c69f29d554 + email: someone@email.com + workspace: + id: 6621ccb459b561c69f29d57c + slug: hitchhikers-workspace + - eventSubType: user_added + eventType: workspace_membership + timestamp: '2025-04-30T20:30:06Z' + actor: + id: 60492e55bbddce079561cd7a + email: someone@webflow.com + workspace: + id: 6621ccb459b561c69f29d57c + slug: hitchhikers-workspace + - eventSubType: user_added + eventType: site_membership + timestamp: '2025-04-30T00:33:31Z' + actor: + id: 671fe00d185fc8c1ad409d37 + email: someone@webflow.com + workspace: + id: 6621ccb459b561c69f29d57c + slug: hitchhikers-workspace + pagination: + limit: 10 + offset: 0 + total: 3 + source: + openapi: ../../../openapi/referenced-specs/v2.yml diff --git a/.mock/fern.config.json b/.mock/fern.config.json index 8b3316e..9c2f634 100644 --- a/.mock/fern.config.json +++ b/.mock/fern.config.json @@ -1,4 +1,4 @@ { "organization" : "webflow", - "version" : "0.46.19" + "version" : "0.110.1" } \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 658601b..ea2269c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. [[package]] name = "annotated-types" @@ -38,13 +38,13 @@ trio = ["trio (>=0.26.1)"] [[package]] name = "certifi" -version = "2024.12.14" +version = "2026.2.25" description = "Python package for providing Mozilla's CA Bundle." optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, - {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, + {file = "certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa"}, + {file = "certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7"}, ] [[package]] @@ -60,15 +60,18 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.2.2" +version = "1.3.1" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, + {file = "exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598"}, + {file = "exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219"}, ] +[package.dependencies] +typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.13\""} + [package.extras] test = ["pytest (>=6)"] @@ -130,13 +133,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "idna" -version = "3.10" +version = "3.11" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, + {file = "idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"}, + {file = "idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"}, ] [package.extras] @@ -144,13 +147,13 @@ all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2 [[package]] name = "iniconfig" -version = "2.0.0" +version = "2.1.0" description = "brain-dead simple config-ini parsing" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, + {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, + {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, ] [[package]] @@ -201,24 +204,24 @@ reports = ["lxml"] [[package]] name = "mypy-extensions" -version = "1.0.0" +version = "1.1.0" description = "Type system extensions for programs checked with the mypy type checker." optional = false -python-versions = ">=3.5" +python-versions = ">=3.8" files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, + {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}, + {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, ] [[package]] name = "packaging" -version = "24.2" +version = "26.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, - {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, + {file = "packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"}, + {file = "packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4"}, ] [[package]] @@ -238,13 +241,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pydantic" -version = "2.10.5" +version = "2.10.6" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.10.5-py3-none-any.whl", hash = "sha256:4dd4e322dbe55472cb7ca7e73f4b63574eecccf2835ffa2af9021ce113c83c53"}, - {file = "pydantic-2.10.5.tar.gz", hash = "sha256:278b38dbbaec562011d659ee05f63346951b3a248a6f3642e1bc68894ea2b4ff"}, + {file = "pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584"}, + {file = "pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236"}, ] [package.dependencies] @@ -473,43 +476,58 @@ files = [ [[package]] name = "tomli" -version = "2.2.1" +version = "2.4.0" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, - {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, - {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, - {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, - {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, - {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, - {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, - {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, - {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, - {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, + {file = "tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867"}, + {file = "tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9"}, + {file = "tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95"}, + {file = "tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76"}, + {file = "tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d"}, + {file = "tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576"}, + {file = "tomli-2.4.0-cp311-cp311-win32.whl", hash = "sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a"}, + {file = "tomli-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa"}, + {file = "tomli-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614"}, + {file = "tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1"}, + {file = "tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8"}, + {file = "tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a"}, + {file = "tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1"}, + {file = "tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b"}, + {file = "tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51"}, + {file = "tomli-2.4.0-cp312-cp312-win32.whl", hash = "sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729"}, + {file = "tomli-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da"}, + {file = "tomli-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3"}, + {file = "tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0"}, + {file = "tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e"}, + {file = "tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4"}, + {file = "tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e"}, + {file = "tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c"}, + {file = "tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f"}, + {file = "tomli-2.4.0-cp313-cp313-win32.whl", hash = "sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86"}, + {file = "tomli-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87"}, + {file = "tomli-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132"}, + {file = "tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6"}, + {file = "tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc"}, + {file = "tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66"}, + {file = "tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d"}, + {file = "tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702"}, + {file = "tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8"}, + {file = "tomli-2.4.0-cp314-cp314-win32.whl", hash = "sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776"}, + {file = "tomli-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475"}, + {file = "tomli-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2"}, + {file = "tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9"}, + {file = "tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0"}, + {file = "tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df"}, + {file = "tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d"}, + {file = "tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f"}, + {file = "tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b"}, + {file = "tomli-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087"}, + {file = "tomli-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd"}, + {file = "tomli-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4"}, + {file = "tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a"}, + {file = "tomli-2.4.0.tar.gz", hash = "sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c"}, ] [[package]] @@ -525,16 +543,16 @@ files = [ [[package]] name = "typing-extensions" -version = "4.12.2" +version = "4.13.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, + {file = "typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c"}, + {file = "typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef"}, ] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "2974ad2d485417c468bff08c2d5526b20e5e4790deaffc5363b3c831bebca3b3" +content-hash = "6f6c191c1028d17a97fdfa84cedfd3cef94b5d63d98b8c1d333b3398eeea9055" diff --git a/pyproject.toml b/pyproject.toml index 58c9529..66a8846 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "webflow" -version = "2.0.0b2" +version = "1.2.1" description = "" readme = "README.md" authors = [] @@ -33,7 +33,6 @@ Repository = 'https://github.com/webflow/webflow-python' [tool.poetry.dependencies] python = "^3.8" httpx = ">=0.21.2" -httpcore = "1.0.9" pydantic = ">= 1.9.2" pydantic-core = "^2.18.2" typing_extensions = ">= 4.0.0" diff --git a/reference.md b/reference.md index 5001bba..9abecdf 100644 --- a/reference.md +++ b/reference.md @@ -137,7 +137,9 @@ client.token.introspect()
-Create a site. This endpoint requires an Enterprise workspace. +Create a site. + +This endpoint requires an Enterprise workspace. Required scope | `workspace:write`
@@ -368,7 +370,9 @@ client.sites.get(
-Delete a site. This endpoint requires an Enterprise workspace. +Delete a site. + +This endpoint requires an Enterprise workspace. Required scope | `sites:write`
@@ -440,7 +444,9 @@ client.sites.delete(
-Update a site. This endpoint requires an Enterprise workspace. +Update a site. + +This endpoint requires an Enterprise workspace. Required scope | `sites:write`
@@ -600,9 +606,11 @@ client.sites.get_custom_domain(
-Publishes a site to one or more more domains. +Publishes a site to one or more more domains. + +To publish to a specific custom domain, use the domain IDs from the [Get Custom Domains](/data/reference/sites/get-custom-domain) endpoint. -This endpoint has a limit of one successful publish queue per minute. +This endpoint has a specific rate limit of one successful publish queue per minute. Required scope | `sites:write`
@@ -626,6 +634,8 @@ client = Webflow( ) client.sites.publish( site_id="580e63e98c9a982ac9b8b741", + custom_domains=["660c6449dd97ebc7346ac629", "660c6449dd97ebc7346ac62f"], + publish_to_webflow_subdomain=False, ) ``` @@ -763,7 +773,9 @@ client.collections.list(
-Create a Collection for a site. +Create a Collection for a site with collection fields. + +Each collection includes the required _name_ and _slug_ fields, which are generated automatically. You can update the `displayName` of these fields, but the slug for them cannot be changed. Fields slugs are automatically converted to lowercase. Spaces in slugs are replaced with hyphens. Required scope | `cms:write`
@@ -780,7 +792,7 @@ Required scope | `cms:write`
```python -from webflow import Webflow +from webflow import ReferenceField, ReferenceFieldMetadata, StaticField, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", @@ -790,6 +802,29 @@ client.collections.create( display_name="Blog Posts", singular_name="Blog Post", slug="posts", + fields=[ + StaticField( + is_required=True, + type="PlainText", + display_name="Title", + help_text="The title of the blog post", + ), + StaticField( + is_required=True, + type="RichText", + display_name="Content", + help_text="The content of the blog post", + ), + ReferenceField( + is_required=True, + type="Reference", + display_name="Author", + help_text="The author of the blog post", + metadata=ReferenceFieldMetadata( + collection_id="23cc2d952d4e4631ffd4345d2743db4e", + ), + ), + ], ) ``` @@ -838,6 +873,14 @@ client.collections.create(
+**fields:** `typing.Optional[typing.Sequence[FieldCreate]]` — An array of custom fields to add to the collection + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -1032,6 +1075,8 @@ client = Webflow( client.pages.list( site_id="580e63e98c9a982ac9b8b741", locale_id="65427cf400e02b306eaa04a0", + limit=1, + offset=1, ) ``` @@ -1056,7 +1101,11 @@ client.pages.list(
-**locale_id:** `typing.Optional[str]` — Unique identifier for a specific locale. Applicable, when using localization. +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization)
@@ -1064,7 +1113,7 @@ client.pages.list(
-**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100)
@@ -1072,7 +1121,7 @@ client.pages.list(
-**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records +**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records
@@ -1153,7 +1202,11 @@ client.pages.get_metadata(
-**locale_id:** `typing.Optional[str]` — Unique identifier for a specific locale. Applicable, when using localization. +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization)
@@ -1202,9 +1255,11 @@ Required scope | `pages:write`
```python -import datetime - -from webflow import PageOpenGraph, PageSeo, Webflow +from webflow import Webflow +from webflow.resources.pages import ( + PageMetadataWriteOpenGraph, + PageMetadataWriteSeo, +) client = Webflow( access_token="YOUR_ACCESS_TOKEN", @@ -1212,32 +1267,18 @@ client = Webflow( client.pages.update_page_settings( page_id="63c720f9347c2139b248e552", locale_id="65427cf400e02b306eaa04a0", - id="6596da6045e56dee495bcbba", - site_id="6258612d1ee792848f805dcf", title="Guide to the Galaxy", slug="guide-to-the-galaxy", - created_on=datetime.datetime.fromisoformat( - "2024-03-11 10:42:00+00:00", - ), - last_updated=datetime.datetime.fromisoformat( - "2024-03-11 10:42:42+00:00", - ), - archived=False, - draft=False, - can_branch=True, - is_branch=False, - seo=PageSeo( + seo=PageMetadataWriteSeo( title="The Ultimate Hitchhiker's Guide to the Galaxy", description="Everything you need to know about the galaxy, from avoiding Vogon poetry to the importance of towels.", ), - open_graph=PageOpenGraph( + open_graph=PageMetadataWriteOpenGraph( title="Explore the Cosmos with The Ultimate Guide", title_copied=False, description="Dive deep into the mysteries of the universe with your guide to everything galactic.", description_copied=False, ), - page_locale_id="653fd9af6a07fc9cfd7a5e57", - published_path="/en-us/guide-to-the-galaxy", ) ``` @@ -1262,95 +1303,11 @@ client.pages.update_page_settings(
-**id:** `str` — Unique identifier for the Page - -
-
- -
-
- -**locale_id:** `typing.Optional[str]` — Unique identifier for a specific locale. Applicable, when using localization. - -
-
- -
-
- -**site_id:** `typing.Optional[str]` — Unique identifier for the Site - -
-
- -
-
- -**title:** `typing.Optional[str]` — Title of the Page - -
-
- -
-
- -**slug:** `typing.Optional[str]` — slug of the Page (derived from title) - -
-
- -
-
- -**parent_id:** `typing.Optional[str]` — Identifier of the parent folder - -
-
- -
-
- -**collection_id:** `typing.Optional[str]` — Unique identifier for a linked Collection, value will be null if the Page is not part of a Collection. - -
-
- -
-
- -**created_on:** `typing.Optional[dt.datetime]` — The date the Page was created - -
-
- -
-
- -**last_updated:** `typing.Optional[dt.datetime]` — The date the Page was most recently updated - -
-
- -
-
- -**archived:** `typing.Optional[bool]` — Whether the Page has been archived - -
-
- -
-
- -**draft:** `typing.Optional[bool]` — Whether the Page is a draft - -
-
+**locale_id:** `typing.Optional[str]` -
-
+Unique identifier for a specific Locale. -**can_branch:** `typing.Optional[bool]` — Indicates whether the Page supports [Page Branching](https://university.webflow.com/lesson/page-branching) +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization)
@@ -1358,7 +1315,7 @@ client.pages.update_page_settings(
-**is_branch:** `typing.Optional[bool]` — Indicates whether the Page is a Branch of another Page [Page Branching](https://university.webflow.com/lesson/page-branching) +**title:** `typing.Optional[str]` — Title for the page
@@ -1366,23 +1323,12 @@ client.pages.update_page_settings(
-**is_members_only:** `typing.Optional[bool]` — Indicates whether the Page is restricted by [Memberships Controls](https://university.webflow.com/lesson/webflow-memberships-overview#how-to-manage-page-restrictions) - -
-
- -
-
+**slug:** `typing.Optional[str]` -**seo:** `typing.Optional[PageSeo]` — SEO-related fields for the Page - -
-
+Slug for the page. -
-
-**open_graph:** `typing.Optional[PageOpenGraph]` — Open Graph fields for the Page +**Note:** Updating slugs in secondary locales is only supported in Advanced and Enterprise localization add-on plans.
@@ -1390,7 +1336,7 @@ client.pages.update_page_settings(
-**page_locale_id:** `typing.Optional[str]` — Unique ID of the page locale +**seo:** `typing.Optional[PageMetadataWriteSeo]` — SEO-related fields for the Page
@@ -1398,7 +1344,7 @@ client.pages.update_page_settings(
-**published_path:** `typing.Optional[str]` — Relative path of the published page URL +**open_graph:** `typing.Optional[PageMetadataWriteOpenGraph]` — Open Graph fields for the Page
@@ -1430,10 +1376,9 @@ client.pages.update_page_settings(
-Get static content from a static page. This includes text nodes, image nodes and component instances. -To retrieve the contents of components in the page use the [get component content](/data/reference/pages-and-components/components/get-content) endpoint. +Get text and component instance content from a static page. -If you do not provide a Locale ID in your request, the response will return any content that can be localized from the Primary locale. +Localization Required scope | `pages:read`
@@ -1458,6 +1403,8 @@ client = Webflow( client.pages.get_content( page_id="63c720f9347c2139b248e552", locale_id="65427cf400e02b306eaa04a0", + limit=1, + offset=1, ) ``` @@ -1482,7 +1429,11 @@ client.pages.get_content(
-**locale_id:** `typing.Optional[str]` — Unique identifier for a specific locale. Applicable, when using localization. +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization)
@@ -1490,7 +1441,7 @@ client.pages.get_content(
-**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100)
@@ -1498,7 +1449,7 @@ client.pages.get_content(
-**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records +**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records
@@ -1533,8 +1484,9 @@ client.pages.get_content( This endpoint updates content on a static page in **secondary locales**. It supports updating up to 1000 nodes in a single request. Before making updates: -1. Use the [get page content](/data/reference/pages-and-components/pages/get-content) endpoint to identify available content nodes and their types -2. If the page has component instances, retrieve the component's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint +1. Use the [get page content](/data/reference/pages-and-components/pages/get-content) endpoint to identify available content nodes and their types. +2. If the page has component instances, retrieve the component's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint. +3. DOM elements may include a `data-w-id` attribute. This attribute is used by Webflow to maintain custom attributes and links across locales. Always include the original `data-w-id` value in your update requests to ensure consistent behavior across all locales. This endpoint is specifically for localized pages. Ensure that the specified `localeId` is a valid **secondary locale** for the site otherwise the request will fail. @@ -1558,6 +1510,10 @@ Required scope | `pages:write` from webflow import ( ComponentInstanceNodePropertyOverridesWrite, ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem, + Select, + SelectNodeWriteChoicesItem, + SubmitButtonNodeWrite, + TextInputNodeWrite, TextNodeWrite, Webflow, ) @@ -1577,6 +1533,28 @@ client.pages.update_static_content( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad627", text="

Don't Panic!

Always know where your towel is.

", ), + Select( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad635", + choices=[ + SelectNodeWriteChoicesItem( + value="choice-1", + text="First choice", + ), + SelectNodeWriteChoicesItem( + value="choice-2", + text="Second choice", + ), + ], + ), + TextInputNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad642", + placeholder="Enter something here...", + ), + SubmitButtonNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad671", + value="Submit", + waiting_text="Submitting...", + ), ComponentInstanceNodePropertyOverridesWrite( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad629", property_overrides=[ @@ -1680,6 +1658,9 @@ client = Webflow( ) client.components.list( site_id="580e63e98c9a982ac9b8b741", + branch_id="68026fa68ef6dc744c75b833", + limit=1, + offset=1, ) ``` @@ -1704,7 +1685,7 @@ client.components.list(
-**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) +**branch_id:** `typing.Optional[str]` — Scope the operation to work on a specific branch.
@@ -1712,7 +1693,15 @@ client.components.list(
-**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100) + +
+
+ +
+
+ +**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records
@@ -1744,7 +1733,7 @@ client.components.list(
-Get static content from a component definition. This includes text nodes, image nodes and nested component instances. +Get static content from a component definition. This includes text nodes, image nodes, select nodes, text input nodes, submit button nodes, and nested component instances. To retrieve dynamic content set by component properties, use the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint. If you do not provide a Locale ID in your request, the response will return any content that can be localized from the Primary locale. @@ -1773,6 +1762,9 @@ client.components.get_content( site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", + limit=1, + offset=1, ) ``` @@ -1805,7 +1797,19 @@ client.components.get_content(
-**locale_id:** `typing.Optional[str]` — Unique identifier for a specific locale. Applicable, when using localization. +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + +
+
+ +
+
+ +**branch_id:** `typing.Optional[str]` — Scope the operation to work on a specific branch.
@@ -1813,7 +1817,7 @@ client.components.get_content(
-**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100)
@@ -1821,7 +1825,7 @@ client.components.get_content(
-**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records +**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records
@@ -1856,8 +1860,9 @@ client.components.get_content( This endpoint updates content within a component defintion for **secondary locales**. It supports updating up to 1000 nodes in a single request. Before making updates: -1. Use the [get component content](/data/reference/pages-and-components/components/get-content) endpoint to identify available content nodes and their types -2. If your component definition has a component instance nested within it, retrieve the nested component instance's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint +1. Use the [get component content](/data/reference/pages-and-components/components/get-content) endpoint to identify available content nodes and their types. +2. If your component definition has a component instance nested within it, retrieve the nested component instance's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint. +3. DOM elements may include a `data-w-id` attribute. This attribute is used by Webflow to maintain custom attributes and links across locales. Always include the original `data-w-id` value in your update requests to ensure consistent behavior across all locales. This endpoint is specifically for localizing component definitions. Ensure that the specified `localeId` is a valid **secondary locale** for the site otherwise the request will fail. @@ -1881,6 +1886,10 @@ Required scope | `components:write` from webflow import ( ComponentInstanceNodePropertyOverridesWrite, ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem, + Select, + SelectNodeWriteChoicesItem, + SubmitButtonNodeWrite, + TextInputNodeWrite, TextNodeWrite, Webflow, ) @@ -1892,6 +1901,7 @@ client.components.update_content( site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", nodes=[ TextNodeWrite( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad623", @@ -1901,6 +1911,28 @@ client.components.update_content( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad627", text="

Don't Panic!

Always know where your towel is.

", ), + Select( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad635", + choices=[ + SelectNodeWriteChoicesItem( + value="choice-1", + text="First choice", + ), + SelectNodeWriteChoicesItem( + value="choice-2", + text="Second choice", + ), + ], + ), + TextInputNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad642", + placeholder="Enter something here...", + ), + SubmitButtonNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad671", + value="Submit", + waiting_text="Submitting...", + ), ComponentInstanceNodePropertyOverridesWrite( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad629", property_overrides=[ @@ -1955,7 +1987,19 @@ client.components.update_content(
-**locale_id:** `typing.Optional[str]` — Unique identifier for a specific locale. Applicable, when using localization. +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + +
+
+ +
+
+ +**branch_id:** `typing.Optional[str]` — Scope the operation to work on a specific branch.
@@ -1987,9 +2031,9 @@ client.components.update_content(
-Get the property default values of a component definition. +Get the default property values of a component definition. -If you do not provide a Locale ID in your request, the response will return any properties that can be localized from the Primary locale. +If you do not include a `localeId` in your request, the response will return any properties that can be localized from the Primary locale. Required scope | `components:read`
@@ -2015,6 +2059,9 @@ client.components.get_properties( site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", + limit=1, + offset=1, ) ``` @@ -2047,7 +2094,19 @@ client.components.get_properties(
-**locale_id:** `typing.Optional[str]` — Unique identifier for a specific locale. Applicable, when using localization. +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + +
+
+ +
+
+ +**branch_id:** `typing.Optional[str]` — Scope the operation to work on a specific branch.
@@ -2055,7 +2114,7 @@ client.components.get_properties(
-**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100)
@@ -2063,7 +2122,7 @@ client.components.get_properties(
-**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records +**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records
@@ -2095,12 +2154,13 @@ client.components.get_properties(
-Update the property default values of a component definition in a specificed locale. +Update the default property values of a component definition in a specificed locale. Before making updates: -1. Use the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint to identify available properties +1. Use the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint to identify properties that can be updated in a secondary locale. +2. Rich Text properties may include a `data-w-id` attribute. This attribute is used by Webflow to maintain links across locales. Always include the original `data-w-id` value in your update requests to ensure consistent behavior across all locales. -The request requires a secondary locale ID. If a locale is missing, the request will not be processed and will result in an error. +The request requires a secondary locale ID. If a `localeId` is missing, the request will not be processed and will result in an error. Required scope | `components:write`
@@ -2127,6 +2187,7 @@ client.components.update_properties( site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", properties=[ ComponentPropertiesWritePropertiesItem( property_id="a245c12d-995b-55ee-5ec7-aa36a6cad623", @@ -2177,7 +2238,19 @@ client.components.update_properties(
-**locale_id:** `typing.Optional[str]` — Unique identifier for a specific locale. Applicable, when using localization. +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + +
+
+ +
+
+ +**branch_id:** `typing.Optional[str]` — Scope the operation to work on a specific branch.
@@ -2210,14 +2283,11 @@ client.components.update_properties(
-List of scripts registered to a Site. - -In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered -to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate -`custom_code` endpoints. -Additionally, Scripts can be remotely hosted, or registered as inline snippets. +Get a list of scripts that have been registered to a site. A site can have a maximum of 800 registered scripts. -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:read`
@@ -2289,14 +2359,11 @@ client.scripts.list(
-Add a script to a Site's Custom Code registry. - -In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered -to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate -`custom_code` endpoints. -Additionally, Scripts can be remotely hosted, or registered as inline snippets. +Register a hosted script to a site. -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write`
@@ -2412,13 +2479,11 @@ client.scripts.register_hosted(
-Add a script to a Site's Custom Code registry. Inline scripts can be between 1 and 2000 characters. - -In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered -to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate -`custom_code` endpoints. +Register an inline script to a site. Inline scripts are limited to 2000 characters. -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write`
@@ -2534,7 +2599,7 @@ client.scripts.register_inline(
-List assets for a given site +List of assets uploaded to a site Required scope | `assets:read`
@@ -2558,6 +2623,8 @@ client = Webflow( ) client.assets.list( site_id="580e63e98c9a982ac9b8b741", + offset=1, + limit=1, ) ``` @@ -2582,6 +2649,22 @@ client.assets.list(
+**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100) + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -2606,15 +2689,18 @@ client.assets.list(
-Create a new asset entry. +The first step in uploading an asset to a site. -This endpoint generates a response with the following information: `uploadUrl` and `uploadDetails`. -You can use these two properties to [upload the file to Amazon s3 by making a POST](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) -request to the `uploadUrl` with the `uploadDetails` object as your header information in the request. +This endpoint generates a response with the following information: `uploadUrl` and `uploadDetails`. - -Required scope | `assets:write` + +Use these properties in the header of a [POST request to Amazson s3](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) to complete the upload. + + +To learn more about how to upload assets to Webflow, see our [assets guide](/data/docs/working-with-assets). + + Required scope | `assets:write`
@@ -2710,7 +2796,7 @@ client.assets.create(
-Get an Asset +Get details about an asset Required scope | `assets:read`
@@ -2854,7 +2940,7 @@ client.assets.delete(
-Update an Asset +Update details of an Asset. Required scope | `assets:write`
@@ -3569,6 +3655,8 @@ client = Webflow( ) client.forms.list( site_id="580e63e98c9a982ac9b8b741", + limit=1, + offset=1, ) ``` @@ -3593,7 +3681,7 @@ client.forms.list(
-**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100)
@@ -3601,7 +3689,7 @@ client.forms.list(
-**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records +**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records
@@ -3707,6 +3795,12 @@ client.forms.get( List form submissions for a given form + + When a form is used in a component definition, each instance of the form is considered a unique form. + + To get a combined list of submissions for a form that appears across multiple component instances, use the [List Form Submissions by Site](/data/reference/forms/form-submissions/list-submissions-by-site) endpoint. + + Required scope | `forms:read`
@@ -3729,6 +3823,8 @@ client = Webflow( ) client.forms.list_submissions( form_id="580e63e98c9a982ac9b8b741", + offset=1, + limit=1, ) ``` @@ -3753,7 +3849,7 @@ client.forms.list_submissions(
-**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records +**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records
@@ -3761,7 +3857,7 @@ client.forms.list_submissions(
-**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100)
@@ -3853,7 +3949,7 @@ client.forms.get_submission(
-
client.forms.update_submission(...) +
client.forms.delete_submission(...)
@@ -3865,7 +3961,8 @@ client.forms.get_submission(
-Update hidden fields on a form submission +Delete a form submission + Required scope | `forms:write`
@@ -3887,7 +3984,7 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.forms.update_submission( +client.forms.delete_submission( form_submission_id="580e63e98c9a982ac9b8b741", ) @@ -3913,14 +4010,6 @@ client.forms.update_submission(
-**form_submission_data:** `typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]` — An existing **hidden field** defined on the form schema, and the corresponding value to set - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -3933,8 +4022,7 @@ client.forms.update_submission(
-## Users -
client.users.list(...) +
client.forms.update_submission(...)
@@ -3946,9 +4034,9 @@ client.forms.update_submission(
-Get a list of users for a site +Update hidden fields on a form submission -Required scope | `users:read` +Required scope | `forms:write`
@@ -3968,8 +4056,8 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.users.list( - site_id="580e63e98c9a982ac9b8b741", +client.forms.update_submission( + form_submission_id="580e63e98c9a982ac9b8b741", ) ``` @@ -3986,23 +4074,7 @@ client.users.list(
-**site_id:** `str` — Unique identifier for a Site - -
-
- -
-
- -**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records - -
-
- -
-
- -**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) +**form_submission_id:** `str` — Unique identifier for a Form Submission
@@ -4010,13 +4082,7 @@ client.users.list(
-**sort:** `typing.Optional[UsersListRequestSort]` - -Sort string to use when ordering users - -Example(`CreatedOn`, `Email`, `Status`, `LastLogin`, `UpdatedOn`). - -Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`) +**form_submission_data:** `typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]` — An existing **hidden field** defined on the form schema, and the corresponding value to set
@@ -4036,7 +4102,8 @@ Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`)
-
client.users.get(...) +## Products +
client.products.list(...)
@@ -4048,9 +4115,12 @@ Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`)
-Get a User by ID +Retrieve all products for a site. + +Use `limit` and `offset` to page through all products with subsequent requests. All SKUs for each product +will also be fetched and returned. The `limit`, `offset` and `total` values represent Products only and do not include any SKUs. -Required scope | `users:read` +Required scope | `ecommerce:read`
@@ -4070,9 +4140,10 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.users.get( +client.products.list( site_id="580e63e98c9a982ac9b8b741", - user_id="580e63e98c9a982ac9b8b741", + offset=1, + limit=1, ) ``` @@ -4097,7 +4168,7 @@ client.users.get(
-**user_id:** `str` — Unique identifier for a User +**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records
@@ -4105,19 +4176,27 @@ client.users.get(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100)
- -
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+ +
-
client.users.delete(...) +
client.products.create(...)
@@ -4129,9 +4208,16 @@ client.users.get(
-Delete a User by ID +Create a new ecommerce product and defaultSKU. A product, at minimum, must have a single SKU. + +To create a product with multiple SKUs: + - First, create a list of `sku-properties`, also known as [product options](https://help.webflow.com/hc/en-us/articles/33961334531347-Create-product-options-and-variants). For example, a T-shirt product may have a "color" `sku-property`, with a list of enum values: red, yellow, and blue, another `sku-property` may be "size", with a list of enum values: small, medium, and large. + - Once, a product is created with a list of `sku-properties`, Webflow will create a **default SKU**, which is always a combination of the first `enum` values of each `sku-property`. (e.g. Small - Red - T-Shirt) + - After creation, you can create additional SKUs for the product, using the [Create SKUs endpoint.](/data/reference/ecommerce/products/create-sku) -Required scope | `users:write` +Upon creation, the default product type will be `Advanced`, which ensures all Product and SKU fields will be shown to users in the Designer. + +Required scope | `ecommerce:write`
@@ -4146,14 +4232,88 @@ Required scope | `users:write`
```python -from webflow import Webflow +from webflow import ( + ProductFieldData, + SkuFieldData, + SkuFieldDataPrice, + SkuPropertyList, + SkuPropertyListEnumItem, + Webflow, +) +from webflow.resources.products import ( + ProductSkuCreateProduct, + ProductSkuCreateSku, +) client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.users.delete( +client.products.create( site_id="580e63e98c9a982ac9b8b741", - user_id="580e63e98c9a982ac9b8b741", + publish_status="staging", + product=ProductSkuCreateProduct( + field_data=ProductFieldData( + name="Colorful T-shirt", + slug="colorful-t-shirt", + description="Our best-selling t-shirt available in multiple colors and sizes", + sku_properties=[ + SkuPropertyList( + id="color", + name="Color", + enum=[ + SkuPropertyListEnumItem( + id="red", + name="Red", + slug="red", + ), + SkuPropertyListEnumItem( + id="yellow", + name="Yellow", + slug="yellow", + ), + SkuPropertyListEnumItem( + id="blue", + name="Blue", + slug="blue", + ), + ], + ), + SkuPropertyList( + id="size", + name="Size", + enum=[ + SkuPropertyListEnumItem( + id="small", + name="Small", + slug="small", + ), + SkuPropertyListEnumItem( + id="medium", + name="Medium", + slug="medium", + ), + SkuPropertyListEnumItem( + id="large", + name="Large", + slug="large", + ), + ], + ), + ], + ), + ), + sku=ProductSkuCreateSku( + field_data=SkuFieldData( + name="Colorful T-shirt - Red Small", + slug="colorful-t-shirt-red-small", + price=SkuFieldDataPrice( + value=2499.0, + unit="USD", + currency="USD", + ), + main_image="https://rocketamp-sample-store.myshopify.com/cdn/shop/products/Gildan_2000_Antique_Cherry_Red_Front_1024x1024.jpg?v=1527232987", + ), + ), ) ``` @@ -4178,7 +4338,23 @@ client.users.delete(
-**user_id:** `str` — Unique identifier for a User +**product:** `ProductSkuCreateProduct` + +
+
+ +
+
+ +**sku:** `ProductSkuCreateSku` + +
+
+ +
+
+ +**publish_status:** `typing.Optional[PublishStatus]`
@@ -4198,7 +4374,7 @@ client.users.delete(
-
client.users.update(...) +
client.products.get(...)
@@ -4210,12 +4386,10 @@ client.users.delete(
-Update a User by ID - - Required scope | `users:write` +Retrieve a single product by its ID. All of its SKUs will also be +retrieved. -The email and password -fields cannot be updated using this endpoint +Required scope | `ecommerce:read`
@@ -4231,20 +4405,13 @@ fields cannot be updated using this endpoint ```python from webflow import Webflow -from webflow.resources.users import UsersUpdateRequestData client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.users.update( +client.products.get( site_id="580e63e98c9a982ac9b8b741", - user_id="580e63e98c9a982ac9b8b741", - data=UsersUpdateRequestData( - name="Some One", - accept_privacy=False, - accept_communications=False, - ), - access_groups=["webflowers", "platinum", "free-tier"], + product_id="580e63fc8c9a982ac9b8b745", ) ``` @@ -4269,24 +4436,7 @@ client.users.update(
-**user_id:** `str` — Unique identifier for a User - -
-
- -
-
- -**data:** `typing.Optional[UsersUpdateRequestData]` - -
-
- -
-
- -**access_groups:** `typing.Optional[typing.Sequence[str]]` — An array of access group slugs. Access groups are assigned to the user as type `admin` and the user remains in the group until removed. - +**product_id:** `str` — Unique identifier for a Product
@@ -4306,7 +4456,7 @@ client.users.update(
-
client.users.invite(...) +
client.products.update(...)
@@ -4318,11 +4468,11 @@ client.users.update(
-Create and invite a user with an email address. +Update an existing Product. -The user will be sent and invite via email, which they will need to accept in order to join paid any paid access group. +Updating an existing Product will set the product type to `Advanced`, which ensures all Product and SKU fields will be shown to users in the Designer. -Required scope | `users:write` +Required scope | `ecommerce:write`
@@ -4342,10 +4492,9 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.users.invite( +client.products.update( site_id="580e63e98c9a982ac9b8b741", - email="some.one@home.com", - access_groups=["webflowers"], + product_id="580e63fc8c9a982ac9b8b745", ) ``` @@ -4370,7 +4519,15 @@ client.users.invite(
-**email:** `str` — Email address of user to send invite to +**product_id:** `str` — Unique identifier for a Product + +
+
+ +
+
+ +**publish_status:** `typing.Optional[PublishStatus]`
@@ -4378,8 +4535,15 @@ client.users.invite(
-**access_groups:** `typing.Optional[typing.Sequence[str]]` — An array of access group slugs. Access groups are assigned to the user as type `admin` and the user remains in the group until removed. +**product:** `typing.Optional[Product]` + +
+
+ +
+
+**sku:** `typing.Optional[Sku]`
@@ -4399,8 +4563,7 @@ client.users.invite(
-## AccessGroups -
client.access_groups.list(...) +
client.products.create_sku(...)
@@ -4412,9 +4575,11 @@ client.users.invite(
-Get a list of access groups for a site +Create additional SKUs to manage every [option and variant of your Product.](https://help.webflow.com/hc/en-us/articles/33961334531347-Create-product-options-and-variants) + +Creating SKUs through the API will set the product type to `Advanced`, which ensures all Product and SKU fields will be shown to users in the Designer. -Required scope | `users:read` +Required scope | `ecommerce:write`
@@ -4429,13 +4594,40 @@ Required scope | `users:read`
```python -from webflow import Webflow +import datetime + +from webflow import Sku, SkuFieldData, SkuFieldDataPrice, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.access_groups.list( +client.products.create_sku( site_id="580e63e98c9a982ac9b8b741", + product_id="580e63fc8c9a982ac9b8b745", + skus=[ + Sku( + id="66072fb71b89448912e2681c", + cms_locale_id="653ad57de882f528b32e810e", + last_published=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + last_updated=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + created_on=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + field_data=SkuFieldData( + name="Colorful T-shirt - Default", + slug="colorful-t-shirt-default", + price=SkuFieldDataPrice( + value=2499.0, + unit="USD", + currency="USD", + ), + ), + ) + ], ) ``` @@ -4460,7 +4652,7 @@ client.access_groups.list(
-**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records +**product_id:** `str` — Unique identifier for a Product
@@ -4468,7 +4660,7 @@ client.access_groups.list(
-**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) +**skus:** `typing.Sequence[Sku]` — An array of the SKU data your are adding
@@ -4476,10 +4668,7 @@ client.access_groups.list(
-**sort:** `typing.Optional[AccessGroupsListRequestSort]` - -Sort string to use when ordering access groups -Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`) +**publish_status:** `typing.Optional[PublishStatus]`
@@ -4499,8 +4688,7 @@ Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`)
-## Products -
client.products.list(...) +
client.products.update_sku(...)
@@ -4512,12 +4700,11 @@ Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`)
-Retrieve all products for a site. +Update a specified SKU. -Use `limit` and `offset` to page through all products with subsequent requests. All SKUs for each product -will also be fetched and returned. The `limit`, `offset` and `total` values represent Products only and do not include any SKUs. +Updating an existing SKU will set the Product type to `Advanced`, which ensures all Product and SKU fields will be shown to users in the Designer. -Required scope | `ecommerce:read` +Required scope | `ecommerce:write`
@@ -4532,13 +4719,39 @@ Required scope | `ecommerce:read`
```python -from webflow import Webflow +import datetime + +from webflow import Sku, SkuFieldData, SkuFieldDataPrice, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.products.list( +client.products.update_sku( site_id="580e63e98c9a982ac9b8b741", + product_id="580e63fc8c9a982ac9b8b745", + sku_id="5e8518516e147040726cc415", + sku=Sku( + id="66072fb71b89448912e2681c", + cms_locale_id="653ad57de882f528b32e810e", + last_published=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + last_updated=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + created_on=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + field_data=SkuFieldData( + name="Colorful T-shirt - Default", + slug="colorful-t-shirt-default", + price=SkuFieldDataPrice( + value=2499.0, + unit="USD", + currency="USD", + ), + ), + ), ) ``` @@ -4563,7 +4776,23 @@ client.products.list(
-**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records +**product_id:** `str` — Unique identifier for a Product + +
+
+ +
+
+ +**sku_id:** `str` — Unique identifier for a SKU + +
+
+ +
+
+ +**sku:** `Sku`
@@ -4571,7 +4800,7 @@ client.products.list(
-**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) +**publish_status:** `typing.Optional[PublishStatus]`
@@ -4591,7 +4820,8 @@ client.products.list(
-
client.products.create(...) +## Orders +
client.orders.list(...)
@@ -4603,20 +4833,9 @@ client.products.list(
-Create a new product and SKU. - -When you create a product, you will always create a SKU, since a Product Item must have, at minimum, a single SKU. - -To create a Product with multiple SKUs - for example a T-shirt in sizes small, medium and large: - - Create parameters in `sku-properties`, also known as [product options and variants.](https://help.webflow.com/hc/en-us/articles/33961334531347-Create-product-options-and-variants). - - A single `sku-property` would be `color`. Within the `color` property, list the various colors of T-shirts as an array of `enum` values: `royal-blue`, `crimson-red`, and `forrest-green`. - - Once, you've created a Product and its `sku-properties` with `enum` values, Webflow will create a **default SKU**, which will automatically be a combination of the first `sku-properties` you've created. - - In our example, the default SKU will be a Royal Blue T-Shirt, because our first `enum` of our Color `sku-property` is Royal Blue. - - After you've created your product, you can create additional SKUs using the [Create SKU endpoint.](/data/reference/ecommerce/products/create-sku) - -Upon creation, the default product type will be `Advanced`, which ensures all Product and SKU fields will be shown to users in the Designer. +List all orders created for a given site. -Required scope | `ecommerce:write` +Required scope | `ecommerce:read`
@@ -4636,8 +4855,11 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.products.create( +client.orders.list( site_id="580e63e98c9a982ac9b8b741", + status="pending", + offset=1, + limit=1, ) ``` @@ -4662,7 +4884,7 @@ client.products.create(
-**publish_status:** `typing.Optional[PublishStatus]` +**status:** `typing.Optional[OrdersListRequestStatus]` — Filter the orders by status
@@ -4670,7 +4892,7 @@ client.products.create(
-**product:** `typing.Optional[Product]` +**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records
@@ -4678,7 +4900,7 @@ client.products.create(
-**sku:** `typing.Optional[Sku]` +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100)
@@ -4698,7 +4920,7 @@ client.products.create(
-
client.products.get(...) +
client.orders.get(...)
@@ -4733,9 +4955,9 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.products.get( +client.orders.get( site_id="580e63e98c9a982ac9b8b741", - product_id="580e63fc8c9a982ac9b8b745", + order_id="5e8518516e147040726cc415", ) ``` @@ -4760,7 +4982,7 @@ client.products.get(
-**product_id:** `str` — Unique identifier for a Product +**order_id:** `str` — Unique identifier for an Order
@@ -4780,7 +5002,7 @@ client.products.get(
-
client.products.update(...) +
client.orders.update(...)
@@ -4792,9 +5014,9 @@ client.products.get(
-Update an existing Product. - -Updating an existing Product will set the product type to `Advanced`, which ensures all Product and SKU fields will be shown to users in the Designer. +This API lets you update the fields, `comment`, `shippingProvider`, +and/or `shippingTracking` for a given order. All three fields can be +updated simultaneously or independently. Required scope | `ecommerce:write`
@@ -4816,9 +5038,9 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.products.update( +client.orders.update( site_id="580e63e98c9a982ac9b8b741", - product_id="580e63fc8c9a982ac9b8b745", + order_id="5e8518516e147040726cc415", ) ``` @@ -4843,7 +5065,7 @@ client.products.update(
-**product_id:** `str` — Unique identifier for a Product +**order_id:** `str` — Unique identifier for an Order
@@ -4851,7 +5073,7 @@ client.products.update(
-**publish_status:** `typing.Optional[PublishStatus]` +**comment:** `typing.Optional[str]` — Arbitrary data for your records
@@ -4859,7 +5081,7 @@ client.products.update(
-**product:** `typing.Optional[Product]` +**shipping_provider:** `typing.Optional[str]` — Company or method used to ship order
@@ -4867,7 +5089,15 @@ client.products.update(
-**sku:** `typing.Optional[Sku]` +**shipping_tracking:** `typing.Optional[str]` — Tracking number for order shipment + +
+
+ +
+
+ +**shipping_tracking_url:** `typing.Optional[str]` — URL to track order shipment
@@ -4887,7 +5117,7 @@ client.products.update(
-
client.products.create_sku(...) +
client.orders.update_fulfill(...)
@@ -4899,9 +5129,7 @@ client.products.update(
-Create additional SKUs to manage every [option and variant of your Product.](https://help.webflow.com/hc/en-us/articles/33961334531347-Create-product-options-and-variants) - -Creating SKUs through the API will set the product type to `Advanced`, which ensures all Product and SKU fields will be shown to users in the Designer. +Updates an order's status to fulfilled Required scope | `ecommerce:write`
@@ -4918,15 +5146,14 @@ Required scope | `ecommerce:write`
```python -from webflow import Sku, Webflow +from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.products.create_sku( +client.orders.update_fulfill( site_id="580e63e98c9a982ac9b8b741", - product_id="580e63fc8c9a982ac9b8b745", - skus=[Sku()], + order_id="5e8518516e147040726cc415", ) ``` @@ -4951,15 +5178,7 @@ client.products.create_sku(
-**product_id:** `str` — Unique identifier for a Product - -
-
- -
-
- -**skus:** `typing.Sequence[Sku]` — An array of the SKU data your are adding +**order_id:** `str` — Unique identifier for an Order
@@ -4967,7 +5186,7 @@ client.products.create_sku(
-**publish_status:** `typing.Optional[PublishStatus]` +**send_order_fulfilled_email:** `typing.Optional[bool]` — Whether or not the Order Fulfilled email should be sent
@@ -4987,7 +5206,7 @@ client.products.create_sku(
-
client.products.update_sku(...) +
client.orders.update_unfulfill(...)
@@ -4999,9 +5218,7 @@ client.products.create_sku(
-Update a specified SKU. - -Updating an existing SKU will set the Product type to `Advanced`, which ensures all Product and SKU fields will be shown to users in the Designer. +Updates an order's status to unfulfilled Required scope | `ecommerce:write`
@@ -5018,16 +5235,14 @@ Required scope | `ecommerce:write`
```python -from webflow import Sku, Webflow +from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.products.update_sku( +client.orders.update_unfulfill( site_id="580e63e98c9a982ac9b8b741", - product_id="580e63fc8c9a982ac9b8b745", - sku_id="5e8518516e147040726cc415", - sku=Sku(), + order_id="5e8518516e147040726cc415", ) ``` @@ -5052,7 +5267,7 @@ client.products.update_sku(
-**product_id:** `str` — Unique identifier for a Product +**order_id:** `str` — Unique identifier for an Order
@@ -5060,48 +5275,23 @@ client.products.update_sku(
-**sku_id:** `str` — Unique identifier for a SKU +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
-
-
-**sku:** `Sku` -
+
+
client.orders.refund(...)
-**publish_status:** `typing.Optional[PublishStatus]` - -
-
- -
-
- -**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. - -
-
- -
- - - -
- - -## Orders -
client.orders.list(...) -
-
- -#### 📝 Description +#### 📝 Description
@@ -5109,9 +5299,10 @@ client.products.update_sku(
-List all orders created for a given site. +This API will reverse a Stripe charge and refund an order back to a +customer. It will also set the order's status to `refunded`. -Required scope | `ecommerce:read` +Required scope | `ecommerce:write`
@@ -5131,8 +5322,9 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.orders.list( +client.orders.refund( site_id="580e63e98c9a982ac9b8b741", + order_id="5e8518516e147040726cc415", ) ``` @@ -5157,15 +5349,7 @@ client.orders.list(
-**status:** `typing.Optional[OrdersListRequestStatus]` — Filter the orders by status - -
-
- -
-
- -**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records +**order_id:** `str` — Unique identifier for an Order
@@ -5173,7 +5357,7 @@ client.orders.list(
-**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) +**reason:** `typing.Optional[OrdersRefundRequestReason]` — The reason for the refund
@@ -5193,7 +5377,8 @@ client.orders.list(
-
client.orders.get(...) +## Inventory +
client.inventory.list(...)
@@ -5205,8 +5390,7 @@ client.orders.list(
-Retrieve a single product by its ID. All of its SKUs will also be -retrieved. +List the current inventory levels for a particular SKU item. Required scope | `ecommerce:read`
@@ -5228,9 +5412,9 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.orders.get( - site_id="580e63e98c9a982ac9b8b741", - order_id="5e8518516e147040726cc415", +client.inventory.list( + sku_collection_id="6377a7c4b7a79608c34a46f7", + sku_id="5e8518516e147040726cc415", ) ``` @@ -5247,7 +5431,7 @@ client.orders.get(
-**site_id:** `str` — Unique identifier for a Site +**sku_collection_id:** `str` — Unique identifier for a SKU collection. Use the List Collections API to find this ID.
@@ -5255,7 +5439,7 @@ client.orders.get(
-**order_id:** `str` — Unique identifier for an Order +**sku_id:** `str` — Unique identifier for a SKU
@@ -5275,7 +5459,7 @@ client.orders.get(
-
client.orders.update(...) +
client.inventory.update(...)
@@ -5287,9 +5471,11 @@ client.orders.get(
-This API lets you update the fields, `comment`, `shippingProvider`, -and/or `shippingTracking` for a given order. All three fields can be -updated simultaneously or independently. +Updates the current inventory levels for a particular SKU item. + +Updates may be given in one or two methods, absolutely or incrementally. +- Absolute updates are done by setting `quantity` directly. +- Incremental updates are by specifying the inventory delta in `updateQuantity` which is then added to the `quantity` stored on the server. Required scope | `ecommerce:write`
@@ -5311,9 +5497,10 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.orders.update( - site_id="580e63e98c9a982ac9b8b741", - order_id="5e8518516e147040726cc415", +client.inventory.update( + sku_collection_id="6377a7c4b7a79608c34a46f7", + sku_id="5e8518516e147040726cc415", + inventory_type="infinite", ) ``` @@ -5330,15 +5517,7 @@ client.orders.update(
-**site_id:** `str` — Unique identifier for a Site - -
-
- -
-
- -**order_id:** `str` — Unique identifier for an Order +**sku_collection_id:** `str` — Unique identifier for a SKU collection. Use the List Collections API to find this ID.
@@ -5346,7 +5525,7 @@ client.orders.update(
-**comment:** `typing.Optional[str]` — Arbitrary data for your records +**sku_id:** `str` — Unique identifier for a SKU
@@ -5354,7 +5533,7 @@ client.orders.update(
-**shipping_provider:** `typing.Optional[str]` — Company or method used to ship order +**inventory_type:** `InventoryUpdateRequestInventoryType` — infinite or finite
@@ -5362,7 +5541,7 @@ client.orders.update(
-**shipping_tracking:** `typing.Optional[str]` — Tracking number for order shipment +**update_quantity:** `typing.Optional[float]` — Adds this quantity to currently store quantity. Can be negative.
@@ -5370,7 +5549,7 @@ client.orders.update(
-**shipping_tracking_url:** `typing.Optional[str]` — URL to track order shipment +**quantity:** `typing.Optional[float]` — Immediately sets quantity to this value.
@@ -5390,7 +5569,8 @@ client.orders.update(
-
client.orders.update_fulfill(...) +## Ecommerce +
client.ecommerce.get_settings(...)
@@ -5402,9 +5582,9 @@ client.orders.update(
-Updates an order's status to fulfilled +Retrieve ecommerce settings for a site. -Required scope | `ecommerce:write` +Required scope | `ecommerce:read`
@@ -5424,9 +5604,8 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.orders.update_fulfill( +client.ecommerce.get_settings( site_id="580e63e98c9a982ac9b8b741", - order_id="5e8518516e147040726cc415", ) ``` @@ -5451,22 +5630,6 @@ client.orders.update_fulfill(
-**order_id:** `str` — Unique identifier for an Order - -
-
- -
-
- -**send_order_fulfilled_email:** `typing.Optional[bool]` — Whether or not the Order Fulfilled email should be sent - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -5479,7 +5642,8 @@ client.orders.update_fulfill(
-
client.orders.update_unfulfill(...) +## Collections Fields +
client.collections.fields.create(...)
@@ -5491,9 +5655,13 @@ client.orders.update_fulfill(
-Updates an order's status to unfulfilled +Create a custom field in a collection. -Required scope | `ecommerce:write` +Field validation is currently not available through the API. + +Bulk creation of fields is not supported with this endpoint. To add multiple fields at once, include them when you [create the collection.](/data/v2.0.0/reference/cms/collections/create) + +Required scope | `cms:write`
@@ -5508,14 +5676,24 @@ Required scope | `ecommerce:write`
```python -from webflow import Webflow +from webflow import ReferenceField, ReferenceFieldMetadata, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.orders.update_unfulfill( - site_id="580e63e98c9a982ac9b8b741", - order_id="5e8518516e147040726cc415", +client.collections.fields.create( + collection_id="580e63fc8c9a982ac9b8b745", + request=ReferenceField( + id="562ac0395358780a1f5e6fbd", + is_editable=True, + is_required=False, + type="Reference", + display_name="Author", + help_text="Add the post author here", + metadata=ReferenceFieldMetadata( + collection_id="63692ab61fb2852f582ba8f5", + ), + ), ) ``` @@ -5532,7 +5710,7 @@ client.orders.update_unfulfill(
-**site_id:** `str` — Unique identifier for a Site +**collection_id:** `str` — Unique identifier for a Collection
@@ -5540,7 +5718,7 @@ client.orders.update_unfulfill(
-**order_id:** `str` — Unique identifier for an Order +**request:** `FieldCreate`
@@ -5560,7 +5738,7 @@ client.orders.update_unfulfill(
-
client.orders.refund(...) +
client.collections.fields.delete(...)
@@ -5572,10 +5750,9 @@ client.orders.update_unfulfill(
-This API will reverse a Stripe charge and refund an order back to a -customer. It will also set the order's status to `refunded`. +Delete a custom field in a collection. This endpoint does not currently support bulk deletion. -Required scope | `ecommerce:write` +Required scope | `cms:write`
@@ -5595,9 +5772,9 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.orders.refund( - site_id="580e63e98c9a982ac9b8b741", - order_id="5e8518516e147040726cc415", +client.collections.fields.delete( + collection_id="580e63fc8c9a982ac9b8b745", + field_id="580e63fc8c9a982ac9b8b745", ) ``` @@ -5614,15 +5791,7 @@ client.orders.refund(
-**site_id:** `str` — Unique identifier for a Site - -
-
- -
-
- -**order_id:** `str` — Unique identifier for an Order +**collection_id:** `str` — Unique identifier for a Collection
@@ -5630,7 +5799,7 @@ client.orders.refund(
-**reason:** `typing.Optional[OrdersRefundRequestReason]` — The reason for the refund +**field_id:** `str` — Unique identifier for a Field in a collection
@@ -5650,8 +5819,7 @@ client.orders.refund(
-## Inventory -
client.inventory.list(...) +
client.collections.fields.update(...)
@@ -5663,9 +5831,9 @@ client.orders.refund(
-List the current inventory levels for a particular SKU item. +Update a custom field in a collection. -Required scope | `ecommerce:read` +Required scope | `cms:write`
@@ -5685,9 +5853,12 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.inventory.list( +client.collections.fields.update( collection_id="580e63fc8c9a982ac9b8b745", - item_id="580e64008c9a982ac9b8b754", + field_id="580e63fc8c9a982ac9b8b745", + is_required=False, + display_name="Post Body", + help_text="Add the body of your post here", ) ``` @@ -5712,7 +5883,31 @@ client.inventory.list(
-**item_id:** `str` — Unique identifier for an Item +**field_id:** `str` — Unique identifier for a Field in a collection + +
+
+ +
+
+ +**is_required:** `typing.Optional[bool]` — Define whether a field is required in a collection + +
+
+ +
+
+ +**display_name:** `typing.Optional[str]` — The name of a field + +
+
+ +
+
+ +**help_text:** `typing.Optional[str]` — Additional text to help anyone filling out this field
@@ -5732,7 +5927,8 @@ client.inventory.list(
-
client.inventory.update(...) +## Collections Items +
client.collections.items.list_items(...)
@@ -5744,13 +5940,9 @@ client.inventory.list(
-Updates the current inventory levels for a particular SKU item. - -Updates may be given in one or two methods, absolutely or incrementally. -- Absolute updates are done by setting `quantity` directly. -- Incremental updates are by specifying the inventory delta in `updateQuantity` which is then added to the `quantity` stored on the server. +List of all Items within a Collection. -Required scope | `ecommerce:write` +Required scope | `CMS:read`
@@ -5770,10 +5962,15 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.inventory.update( +client.collections.items.list_items( collection_id="580e63fc8c9a982ac9b8b745", - item_id="580e64008c9a982ac9b8b754", - inventory_type="infinite", + cms_locale_id="cmsLocaleId", + offset=1, + limit=1, + name="name", + slug="slug", + sort_by="lastPublished", + sort_order="asc", ) ``` @@ -5798,7 +5995,7 @@ client.inventory.update(
-**item_id:** `str` — Unique identifier for an Item +**cms_locale_id:** `typing.Optional[str]` — Unique identifier for a CMS Locale. This UID is different from the Site locale identifier and is listed as `cmsLocaleId` in the Sites response. To query multiple locales, input a comma separated string.
@@ -5806,7 +6003,7 @@ client.inventory.update(
-**inventory_type:** `InventoryUpdateRequestInventoryType` — infinite or finite +**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records
@@ -5814,7 +6011,7 @@ client.inventory.update(
-**update_quantity:** `typing.Optional[float]` — Adds this quantity to currently store quantity. Can be negative. +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100)
@@ -5822,7 +6019,39 @@ client.inventory.update(
-**quantity:** `typing.Optional[float]` — Immediately sets quantity to this value. +**name:** `typing.Optional[str]` — Filter by the exact name of the item(s) + +
+
+ +
+
+ +**slug:** `typing.Optional[str]` — Filter by the exact slug of the item + +
+
+ +
+
+ +**last_published:** `typing.Optional[ItemsListItemsRequestLastPublished]` — Filter by the last published date of the item(s) + +
+
+ +
+
+ +**sort_by:** `typing.Optional[ItemsListItemsRequestSortBy]` — Sort results by the provided value + +
+
+ +
+
+ +**sort_order:** `typing.Optional[ItemsListItemsRequestSortOrder]` — Sorts the results by asc or desc
@@ -5842,8 +6071,7 @@ client.inventory.update(
-## Ecommerce -
client.ecommerce.get_settings(...) +
client.collections.items.create_item(...)
@@ -5855,9 +6083,12 @@ client.inventory.update(
-Retrieve ecommerce settings for a site. +Create Item(s) in a Collection. -Required scope | `ecommerce:read` + +To create items across multiple locales, please use [this endpoint.](/data/reference/cms/collection-items/staged-items/create-items) + +Required scope | `CMS:write`
@@ -5872,97 +6103,39 @@ Required scope | `ecommerce:read`
```python -from webflow import Webflow - -client = Webflow( - access_token="YOUR_ACCESS_TOKEN", -) -client.ecommerce.get_settings( - site_id="580e63e98c9a982ac9b8b741", +from webflow import ( + CollectionItemPostSingle, + CollectionItemPostSingleFieldData, + Webflow, ) - -``` -
-
- - - -#### ⚙️ Parameters - -
-
- -
-
- -**site_id:** `str` — Unique identifier for a Site - -
-
- -
-
- -**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. - -
-
-
-
- - - - -
- -## Collections Fields -
client.collections.fields.create(...) -
-
- -#### 📝 Description - -
-
- -
-
- -Create a custom field in a collection. - -Slugs must be all lowercase letters without spaces. -If you pass a string with uppercase letters and/or spaces to the "Slug" property, Webflow will -convert the slug to lowercase and replace spaces with "-." - -Only some field types can be created through the API. -This endpoint does not currently support bulk creation. - -Required scope | `cms:write` -
-
-
-
- -#### 🔌 Usage - -
-
- -
-
- -```python -from webflow import Webflow +from webflow.resources.collections.resources.items import MultipleItems client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.collections.fields.create( +client.collections.items.create_item( collection_id="580e63fc8c9a982ac9b8b745", - is_required=False, - type="RichText", - display_name="Post Body", - help_text="Add the body of your post here", + skip_invalid_files=True, + request=MultipleItems( + items=[ + CollectionItemPostSingle( + is_archived=False, + is_draft=False, + field_data=CollectionItemPostSingleFieldData( + name="Senior Data Analyst", + slug="senior-data-analyst", + ), + ), + CollectionItemPostSingle( + is_archived=False, + is_draft=False, + field_data=CollectionItemPostSingleFieldData( + name="Product Manager", + slug="product-manager", + ), + ), + ], + ), ) ``` @@ -5987,23 +6160,7 @@ client.collections.fields.create(
-**type:** `FieldCreateType` — Choose these appropriate field type for your collection data - -
-
- -
-
- -**display_name:** `str` — The name of a field - -
-
- -
-
- -**is_required:** `typing.Optional[bool]` — define whether a field is required in a collection +**request:** `ItemsCreateItemRequestBody`
@@ -6011,7 +6168,7 @@ client.collections.fields.create(
-**help_text:** `typing.Optional[str]` — Additional text to help anyone filling out this field +**skip_invalid_files:** `typing.Optional[bool]` — When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid.
@@ -6031,7 +6188,7 @@ client.collections.fields.create(
-
client.collections.fields.delete(...) +
client.collections.items.delete_items(...)
@@ -6043,9 +6200,11 @@ client.collections.fields.create(
-Delete a custom field in a collection. This endpoint does not currently support bulk deletion. +Delete Items from a Collection. -Required scope | `cms:write` +Items will only be deleted in the primary locale unless a `cmsLocaleId` is included in the request. + +Required scope | `CMS:write`
@@ -6061,13 +6220,20 @@ Required scope | `cms:write` ```python from webflow import Webflow +from webflow.resources.collections.resources.items import ( + ItemsDeleteItemsRequestItemsItem, +) client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.collections.fields.delete( +client.collections.items.delete_items( collection_id="580e63fc8c9a982ac9b8b745", - field_id="580e63fc8c9a982ac9b8b745", + items=[ + ItemsDeleteItemsRequestItemsItem( + id="580e64008c9a982ac9b8b754", + ) + ], ) ``` @@ -6092,7 +6258,7 @@ client.collections.fields.delete(
-**field_id:** `str` — Unique identifier for a Field in a collection +**items:** `typing.Sequence[ItemsDeleteItemsRequestItemsItem]`
@@ -6112,7 +6278,7 @@ client.collections.fields.delete(
-
client.collections.fields.update(...) +
client.collections.items.update_items(...)
@@ -6124,9 +6290,13 @@ client.collections.fields.delete(
-Update a custom field in a collection. +Update a single item or multiple items in a Collection. -Required scope | `cms:write` +The limit for this endpoint is 100 items. + +Items will only be updated in the primary locale, unless a `cmsLocaleId` is included in the request. + +Required scope | `CMS:write`
@@ -6141,17 +6311,38 @@ Required scope | `cms:write`
```python -from webflow import Webflow +from webflow import ( + CollectionItemWithIdInput, + CollectionItemWithIdInputFieldData, + Webflow, +) client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.collections.fields.update( +client.collections.items.update_items( collection_id="580e63fc8c9a982ac9b8b745", - field_id="580e63fc8c9a982ac9b8b745", - is_required=False, - display_name="Post Body", - help_text="Add the body of your post here", + skip_invalid_files=True, + items=[ + CollectionItemWithIdInput( + id="580e64008c9a982ac9b8b754", + is_archived=False, + is_draft=False, + field_data=CollectionItemWithIdInputFieldData( + name="Senior Data Analyst", + slug="senior-data-analyst", + ), + ), + CollectionItemWithIdInput( + id="580e64008c9a982ac9b8b754", + is_archived=False, + is_draft=False, + field_data=CollectionItemWithIdInputFieldData( + name="Product Manager", + slug="product-manager", + ), + ), + ], ) ``` @@ -6176,23 +6367,7 @@ client.collections.fields.update(
-**field_id:** `str` — Unique identifier for a Field in a collection - -
-
- -
-
- -**is_required:** `typing.Optional[bool]` — Define whether a field is required in a collection - -
-
- -
-
- -**display_name:** `typing.Optional[str]` — The name of a field +**skip_invalid_files:** `typing.Optional[bool]` — When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid.
@@ -6200,7 +6375,7 @@ client.collections.fields.update(
-**help_text:** `typing.Optional[str]` — Additional text to help anyone filling out this field +**items:** `typing.Optional[typing.Sequence[CollectionItemWithIdInput]]`
@@ -6220,8 +6395,7 @@ client.collections.fields.update(
-## Collections Items -
client.collections.items.list_items(...) +
client.collections.items.list_items_live(...)
@@ -6233,7 +6407,11 @@ client.collections.fields.update(
-List of all Items within a Collection. +List all published items in a collection. + + + Serving data to applications in real-time? Use the Content Delivery API at `api-cdn.webflow.com` for better performance. The CDN-backed endpoint is optimized for high-volume reads, while the Data API is designed for writes and management operations. + Required scope | `CMS:read`
@@ -6255,8 +6433,15 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.collections.items.list_items( +client.collections.items.list_items_live( collection_id="580e63fc8c9a982ac9b8b745", + cms_locale_id="cmsLocaleId", + offset=1, + limit=1, + name="name", + slug="slug", + sort_by="lastPublished", + sort_order="asc", ) ``` @@ -6289,7 +6474,7 @@ client.collections.items.list_items(
-**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records +**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records
@@ -6297,7 +6482,7 @@ client.collections.items.list_items(
-**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100)
@@ -6305,7 +6490,7 @@ client.collections.items.list_items(
-**name:** `typing.Optional[str]` — The name of the item(s) +**name:** `typing.Optional[str]` — Filter by the exact name of the item(s)
@@ -6313,7 +6498,7 @@ client.collections.items.list_items(
-**slug:** `typing.Optional[str]` — The slug of the item +**slug:** `typing.Optional[str]` — Filter by the exact slug of the item
@@ -6321,7 +6506,7 @@ client.collections.items.list_items(
-**sort_by:** `typing.Optional[ItemsListItemsRequestSortBy]` — Sort results by the provided value +**last_published:** `typing.Optional[ItemsListItemsLiveRequestLastPublished]` — Filter by the last published date of the item(s)
@@ -6329,7 +6514,15 @@ client.collections.items.list_items(
-**sort_order:** `typing.Optional[ItemsListItemsRequestSortOrder]` — Sorts the results by asc or desc +**sort_by:** `typing.Optional[ItemsListItemsLiveRequestSortBy]` — Sort results by the provided value + +
+
+ +
+
+ +**sort_order:** `typing.Optional[ItemsListItemsLiveRequestSortOrder]` — Sorts the results by asc or desc
@@ -6349,7 +6542,7 @@ client.collections.items.list_items(
-
client.collections.items.create_item(...) +
client.collections.items.create_item_live(...)
@@ -6361,10 +6554,11 @@ client.collections.items.list_items(
-Create Item(s) in a Collection. +Create item(s) in a collection that will be immediately published to the live site. -To create items across multiple locales, please use [this endpoint.](/v2.0.0/data/reference/cms/collection-items/staged-items/create-items) +To create items across multiple locales, [please use this endpoint.](/data/reference/cms/collection-items/staged-items/create-items) + Required scope | `CMS:write`
@@ -6381,32 +6575,29 @@ Required scope | `CMS:write`
```python -from webflow import ( - CollectionItemPostSingle, - CollectionItemPostSingleFieldData, - Webflow, -) -from webflow.resources.collections.resources.items import MultipleItems +from webflow import CollectionItem, CollectionItemFieldData, Webflow +from webflow.resources.collections.resources.items import MultipleLiveItems client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.collections.items.create_item( +client.collections.items.create_item_live( collection_id="580e63fc8c9a982ac9b8b745", - request=MultipleItems( + skip_invalid_files=True, + request=MultipleLiveItems( items=[ - CollectionItemPostSingle( + CollectionItem( is_archived=False, is_draft=False, - field_data=CollectionItemPostSingleFieldData( + field_data=CollectionItemFieldData( name="Senior Data Analyst", slug="senior-data-analyst", ), ), - CollectionItemPostSingle( + CollectionItem( is_archived=False, is_draft=False, - field_data=CollectionItemPostSingleFieldData( + field_data=CollectionItemFieldData( name="Product Manager", slug="product-manager", ), @@ -6437,7 +6628,15 @@ client.collections.items.create_item(
-**request:** `ItemsCreateItemRequest` +**request:** `ItemsCreateItemLiveRequestBody` + +
+
+ +
+
+ +**skip_invalid_files:** `typing.Optional[bool]` — When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid.
@@ -6457,7 +6656,7 @@ client.collections.items.create_item(
-
client.collections.items.delete_items(...) +
client.collections.items.delete_items_live(...)
@@ -6469,9 +6668,9 @@ client.collections.items.create_item(
-Delete Items from a Collection. +Unpublish up to 100 items from the live site and set the `isDraft` property to `true`. -**Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be deleted only in the primary locale. +Items will only be unpublished in the primary locale unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write`
@@ -6489,12 +6688,20 @@ Required scope | `CMS:write` ```python from webflow import Webflow +from webflow.resources.collections.resources.items import ( + ItemsDeleteItemsLiveRequestItemsItem, +) client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.collections.items.delete_items( +client.collections.items.delete_items_live( collection_id="580e63fc8c9a982ac9b8b745", + items=[ + ItemsDeleteItemsLiveRequestItemsItem( + id="580e64008c9a982ac9b8b754", + ) + ], ) ``` @@ -6519,7 +6726,7 @@ client.collections.items.delete_items(
-**items:** `typing.Optional[typing.Sequence[ItemsDeleteItemsRequestItemsItem]]` +**items:** `typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem]`
@@ -6539,7 +6746,7 @@ client.collections.items.delete_items(
-
client.collections.items.update_items(...) +
client.collections.items.update_items_live(...)
@@ -6551,9 +6758,9 @@ client.collections.items.delete_items(
-Update a single item or multiple items (up to 100) in a Collection. +Update a single published item or multiple published items (up to 100) in a Collection -**Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be updated only in the primary locale. +Items will only be updated in the primary locale, unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write`
@@ -6579,8 +6786,9 @@ from webflow import ( client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.collections.items.update_items( +client.collections.items.update_items_live( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, items=[ CollectionItemWithIdInput( id="66f6ed9576ddacf3149d5ea6", @@ -6639,6 +6847,14 @@ client.collections.items.update_items(
+**skip_invalid_files:** `typing.Optional[bool]` — When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + +
+
+ +
+
+ **items:** `typing.Optional[typing.Sequence[CollectionItemWithIdInput]]`
@@ -6659,7 +6875,7 @@ client.collections.items.update_items(
-
client.collections.items.list_items_live(...) +
client.collections.items.create_items(...)
@@ -6671,12 +6887,17 @@ client.collections.items.update_items(
-List of all live Items within a Collection. +Create an item or multiple items in a CMS Collection across multiple corresponding locales. -Required scope | `CMS:read` -
-
-
+ + - This endpoint can create up to 100 items in a request. + - If the `cmsLocaleIds` parameter is not included in the request, an item will only be created in the primary locale. + + +Required scope | `CMS:write` + +
+ #### 🔌 Usage @@ -6689,12 +6910,25 @@ Required scope | `CMS:read` ```python from webflow import Webflow +from webflow.resources.collections.resources.items import SingleCmsItem client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.collections.items.list_items_live( +client.collections.items.create_items( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, + cms_locale_ids=[ + "66f6e966c9e1dc700a857ca3", + "66f6e966c9e1dc700a857ca4", + "66f6e966c9e1dc700a857ca5", + ], + is_archived=False, + is_draft=False, + field_data=SingleCmsItem( + name="Don’t Panic", + slug="dont-panic", + ), ) ``` @@ -6719,23 +6953,7 @@ client.collections.items.list_items_live(
-**cms_locale_id:** `typing.Optional[str]` — Unique identifier for a CMS Locale. This UID is different from the Site locale identifier and is listed as `cmsLocaleId` in the Sites response. To query multiple locales, input a comma separated string. - -
-
- -
-
- -**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records - -
-
- -
-
- -**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) +**field_data:** `CreateBulkCollectionItemRequestBodyFieldData`
@@ -6743,7 +6961,7 @@ client.collections.items.list_items_live(
-**name:** `typing.Optional[str]` — The name of the item(s) +**skip_invalid_files:** `typing.Optional[bool]` — When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid.
@@ -6751,7 +6969,7 @@ client.collections.items.list_items_live(
-**slug:** `typing.Optional[str]` — The slug of the item +**cms_locale_ids:** `typing.Optional[typing.Sequence[str]]` — Array of identifiers for the locales where the item will be created
@@ -6759,7 +6977,7 @@ client.collections.items.list_items_live(
-**sort_by:** `typing.Optional[ItemsListItemsLiveRequestSortBy]` — Sort results by the provided value +**is_archived:** `typing.Optional[bool]` — Indicates whether the item is archived.
@@ -6767,7 +6985,7 @@ client.collections.items.list_items_live(
-**sort_order:** `typing.Optional[ItemsListItemsLiveRequestSortOrder]` — Sorts the results by asc or desc +**is_draft:** `typing.Optional[bool]` — Indicates whether the item is in draft state.
@@ -6787,7 +7005,7 @@ client.collections.items.list_items_live(
-
client.collections.items.create_item_live(...) +
client.collections.items.get_item(...)
@@ -6799,13 +7017,9 @@ client.collections.items.list_items_live(
-Create live Item(s) in a Collection. The Item(s) will be published to the live site. - - -To create items across multiple locales, [please use this endpoint.](/v2.0.0/data/reference/cms/collection-items/staged-items/create-items) - +Get details of a selected Collection Item. -Required scope | `CMS:write` +Required scope | `CMS:read`
@@ -6820,34 +7034,15 @@ Required scope | `CMS:write`
```python -from webflow import CollectionItem, CollectionItemFieldData, Webflow -from webflow.resources.collections.resources.items import MultipleLiveItems +from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.collections.items.create_item_live( +client.collections.items.get_item( collection_id="580e63fc8c9a982ac9b8b745", - request=MultipleLiveItems( - items=[ - CollectionItem( - is_archived=False, - is_draft=False, - field_data=CollectionItemFieldData( - name="Senior Data Analyst", - slug="senior-data-analyst", - ), - ), - CollectionItem( - is_archived=False, - is_draft=False, - field_data=CollectionItemFieldData( - name="Product Manager", - slug="product-manager", - ), - ), - ], - ), + item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) ``` @@ -6872,7 +7067,15 @@ client.collections.items.create_item_live(
-**request:** `ItemsCreateItemLiveRequest` +**item_id:** `str` — Unique identifier for an Item + +
+
+ +
+
+ +**cms_locale_id:** `typing.Optional[str]` — Unique identifier for a CMS Locale. This UID is different from the Site locale identifier and is listed as `cmsLocaleId` in the Sites response. To query multiple locales, input a comma separated string.
@@ -6892,7 +7095,7 @@ client.collections.items.create_item_live(
-
client.collections.items.delete_items_live(...) +
client.collections.items.delete_item(...)
@@ -6904,9 +7107,7 @@ client.collections.items.create_item_live(
-Remove an item or multiple items (up to 100 items) from the live site. Deleting published items will unpublish the items from the live site and set them to draft. - -**Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be unpublished only in the primary locale. +Delete an item from a collection. Required scope | `CMS:write`
@@ -6928,8 +7129,10 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.collections.items.delete_items_live( +client.collections.items.delete_item( collection_id="580e63fc8c9a982ac9b8b745", + item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) ``` @@ -6954,7 +7157,15 @@ client.collections.items.delete_items_live(
-**items:** `typing.Optional[typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem]]` +**item_id:** `str` — Unique identifier for an Item + +
+
+ +
+
+ +**cms_locale_id:** `typing.Optional[str]` — Unique identifier for a CMS Locale. This UID is different from the Site locale identifier and is listed as `cmsLocaleId` in the Sites response. To query multiple locales, input a comma separated string.
@@ -6974,7 +7185,7 @@ client.collections.items.delete_items_live(
-
client.collections.items.update_items_live(...) +
client.collections.items.update_item(...)
@@ -6986,9 +7197,7 @@ client.collections.items.delete_items_live(
-Update a single live item or multiple live items (up to 100) in a Collection - -**Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be updated only in the primary locale. +Update a selected Item in a Collection. Required scope | `CMS:write`
@@ -7005,51 +7214,21 @@ Required scope | `CMS:write`
```python -from webflow import ( - CollectionItemWithIdInput, - CollectionItemWithIdInputFieldData, - Webflow, -) +from webflow import CollectionItemPatchSingleFieldData, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.collections.items.update_items_live( +client.collections.items.update_item( collection_id="580e63fc8c9a982ac9b8b745", - items=[ - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5ea6", - cms_locale_id="66f6e966c9e1dc700a857ca5", - field_data=CollectionItemWithIdInputFieldData( - name="Ne Paniquez Pas", - slug="ne-paniquez-pas", - ), - ), - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5ea6", - cms_locale_id="66f6e966c9e1dc700a857ca4", - field_data=CollectionItemWithIdInputFieldData( - name="No Entrar en Pánico", - slug="no-entrar-en-panico", - ), - ), - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5eaa", - cms_locale_id="66f6e966c9e1dc700a857ca5", - field_data=CollectionItemWithIdInputFieldData( - name="Au Revoir et Merci pour Tous les Poissons", - slug="au-revoir-et-merci", - ), - ), - CollectionItemWithIdInput( - id="66f6ed9576ddacf3149d5eaa", - cms_locale_id="66f6e966c9e1dc700a857ca4", - field_data=CollectionItemWithIdInputFieldData( - name="Hasta Luego y Gracias por Todo el Pescado", - slug="hasta-luego-y-gracias", - ), - ), - ], + item_id="580e64008c9a982ac9b8b754", + skip_invalid_files=True, + is_archived=False, + is_draft=False, + field_data=CollectionItemPatchSingleFieldData( + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", + ), ) ``` @@ -7074,7 +7253,7 @@ client.collections.items.update_items_live(
-**items:** `typing.Optional[typing.Sequence[CollectionItemWithIdInput]]` +**item_id:** `str` — Unique identifier for an Item
@@ -7082,87 +7261,39 @@ client.collections.items.update_items_live(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**skip_invalid_files:** `typing.Optional[bool]` — When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid.
-
-
- - -
-
-
-
client.collections.items.create_items(...)
-#### 📝 Description - -
-
+**id:** `typing.Optional[str]` — Unique identifier for the Item + +
+
-Create an item or multiple items in a CMS Collection across multiple corresponding locales. - -**Notes:** - - This endpoint can create up to 100 items in a request. - - If the `cmsLocaleIds` parameter is undefined or empty and localization is enabled, items will only be created in the primary locale. - -Required scope | `CMS:write` -
-
+**cms_locale_id:** `typing.Optional[str]` — Identifier for the locale of the CMS item +
-#### 🔌 Usage - -
-
-
-```python -from webflow import Webflow -from webflow.resources.collections.resources.items import SingleCmsItem - -client = Webflow( - access_token="YOUR_ACCESS_TOKEN", -) -client.collections.items.create_items( - collection_id="580e63fc8c9a982ac9b8b745", - cms_locale_ids=[ - "66f6e966c9e1dc700a857ca3", - "66f6e966c9e1dc700a857ca4", - "66f6e966c9e1dc700a857ca5", - ], - is_archived=False, - is_draft=False, - field_data=SingleCmsItem( - name="Don’t Panic", - slug="dont-panic", - ), -) - -``` -
-
+**last_published:** `typing.Optional[str]` — The date the item was last published +
-#### ⚙️ Parameters - -
-
-
-**collection_id:** `str` — Unique identifier for a Collection +**last_updated:** `typing.Optional[str]` — The date the item was last updated
@@ -7170,7 +7301,7 @@ client.collections.items.create_items(
-**field_data:** `CreateBulkCollectionItemRequestBodyFieldData` +**created_on:** `typing.Optional[str]` — The date the item was created
@@ -7178,7 +7309,7 @@ client.collections.items.create_items(
-**cms_locale_ids:** `typing.Optional[typing.Sequence[str]]` — Array of identifiers for the locales where the item will be created +**is_archived:** `typing.Optional[bool]` — Boolean determining if the Item is set to archived
@@ -7186,7 +7317,7 @@ client.collections.items.create_items(
-**is_archived:** `typing.Optional[bool]` — Indicates whether the item is archived. +**is_draft:** `typing.Optional[bool]` — Boolean determining if the Item is set to draft
@@ -7194,7 +7325,7 @@ client.collections.items.create_items(
-**is_draft:** `typing.Optional[bool]` — Indicates whether the item is in draft state. +**field_data:** `typing.Optional[CollectionItemPatchSingleFieldData]`
@@ -7214,7 +7345,7 @@ client.collections.items.create_items(
-
client.collections.items.get_item(...) +
client.collections.items.get_item_live(...)
@@ -7226,7 +7357,11 @@ client.collections.items.create_items(
-Get details of a selected Collection Item. +Get details of a selected Collection live Item. + + + Serving data to applications in real-time? Use the Content Delivery API at `api-cdn.webflow.com` for better performance. The CDN-backed endpoint is optimized for high-volume reads, while the Data API is designed for writes and management operations. + Required scope | `CMS:read`
@@ -7248,9 +7383,10 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.collections.items.get_item( +client.collections.items.get_item_live( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) ``` @@ -7303,7 +7439,7 @@ client.collections.items.get_item(
-
client.collections.items.delete_item(...) +
client.collections.items.delete_item_live(...)
@@ -7315,7 +7451,9 @@ client.collections.items.get_item(
-Delete an Item from a Collection. This endpoint does not currently support bulk deletion. +Unpublish a live item from the site and set the `isDraft` property to `true`. + +For bulk unpublishing, please use [this endpoint.](/data/v2.0.0/reference/cms/collection-items/live-items/delete-items-live) Required scope | `CMS:write`
@@ -7337,9 +7475,10 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.collections.items.delete_item( +client.collections.items.delete_item_live( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) ``` @@ -7392,7 +7531,7 @@ client.collections.items.delete_item(
-
client.collections.items.update_item(...) +
client.collections.items.update_item_live(...)
@@ -7404,7 +7543,7 @@ client.collections.items.delete_item(
-Update a selected Item in a Collection. +Update a selected live Item in a Collection. The updates for this Item will be published to the live site. Required scope | `CMS:write`
@@ -7426,14 +7565,15 @@ from webflow import CollectionItemPatchSingleFieldData, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.collections.items.update_item( +client.collections.items.update_item_live( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + skip_invalid_files=True, is_archived=False, is_draft=False, field_data=CollectionItemPatchSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", ), ) @@ -7467,6 +7607,14 @@ client.collections.items.update_item(
+**skip_invalid_files:** `typing.Optional[bool]` — When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + +
+
+ +
+
+ **id:** `typing.Optional[str]` — Unique identifier for the Item
@@ -7543,7 +7691,7 @@ client.collections.items.update_item(
-
client.collections.items.get_item_live(...) +
client.collections.items.publish_item(...)
@@ -7555,9 +7703,9 @@ client.collections.items.update_item(
-Get details of a selected Collection live Item. +Publish an item or multiple items. -Required scope | `CMS:read` +Required scope | `cms:write`
@@ -7573,13 +7721,28 @@ Required scope | `CMS:read` ```python from webflow import Webflow +from webflow.resources.collections.resources.items import ( + ItemIDsWithLocales, + ItemsPublishItemRequestItemsItemsItem, +) client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.collections.items.get_item_live( +client.collections.items.publish_item( collection_id="580e63fc8c9a982ac9b8b745", - item_id="580e64008c9a982ac9b8b754", + request=ItemIDsWithLocales( + items=[ + ItemsPublishItemRequestItemsItemsItem( + id="643fd856d66b6528195ee2ca", + cms_locale_ids=[ + "653ad57de882f528b32e810e", + "6514390aea353fc691d69827", + "65143930ea353fc691d69cd8", + ], + ) + ], + ), ) ``` @@ -7604,7 +7767,983 @@ client.collections.items.get_item_live(
-**item_id:** `str` — Unique identifier for an Item +**request:** `ItemsPublishItemRequest` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+ +
+ + + + +
+ +## Pages Scripts +
client.pages.scripts.get_custom_code(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get all scripts applied to a page. + +Required scope | `custom_code:read` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.pages.scripts.get_custom_code( + page_id="63c720f9347c2139b248e552", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**page_id:** `str` — Unique identifier for a Page + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.pages.scripts.upsert_custom_code(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Apply registered scripts to a page. If you have multiple scripts your App needs to apply or maintain on a page, ensure they are always included in the request body for this endpoint. To remove individual scripts, simply call this endpoint without the script in the request body. + + + To apply a script to a page, the script must first be registered to a Site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + + +Required scope | `custom_code:write` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import ScriptApply, Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.pages.scripts.upsert_custom_code( + page_id="63c720f9347c2139b248e552", + scripts=[ + ScriptApply( + id="cms_slider", + location="header", + version="1.0.0", + attributes={"my-attribute": "some-value"}, + ), + ScriptApply( + id="alert", + location="header", + version="0.0.1", + ), + ], +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**page_id:** `str` — Unique identifier for a Page + +
+
+ +
+
+ +**scripts:** `typing.Optional[typing.Sequence[ScriptApply]]` — A list of scripts applied to a Site or a Page + +
+
+ +
+
+ +**last_updated:** `typing.Optional[str]` — Date when the Site's scripts were last updated + +
+
+ +
+
+ +**created_on:** `typing.Optional[str]` — Date when the Site's scripts were created + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.pages.scripts.delete_custom_code(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Remove all scripts from a page applied by the App. This endpoint will not remove scripts from the site's registered scripts. + +To remove individual scripts applied by the App, use the [Add/Update Custom Code](/data/reference/custom-code/custom-code-pages/upsert-custom-code) endpoint. + +Access to this endpoint requires a bearer token obtained from an [OAuth Code Grant Flow](/data/reference/oauth-app). + +Required scope | `custom_code:write` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.pages.scripts.delete_custom_code( + page_id="63c720f9347c2139b248e552", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**page_id:** `str` — Unique identifier for a Page + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Sites Redirects +
client.sites.redirects.list(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Fetch a list of all 301 redirect rules configured for a specific site. + +Use this endpoint to review, audit, or manage the redirection rules that control how traffic is rerouted on your site. + +This endpoint requires an Enterprise workspace. + +Required scope: `sites:read` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.redirects.list( + site_id="580e63e98c9a982ac9b8b741", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.sites.redirects.create(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Add a new 301 redirection rule to a site. + +This endpoint allows you to define a source path (`fromUrl`) and its corresponding destination path (`toUrl`), which will dictate how traffic is rerouted on your site. This is useful for managing site changes, restructuring URLs, or handling outdated links. + +This endpoint requires an Enterprise workspace. + +Required scope: `sites:write` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.redirects.create( + site_id="580e63e98c9a982ac9b8b741", + id="42e1a2b7aa1a13f768a0042a", + from_url="/mostly-harmless", + to_url="/earth", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**id:** `typing.Optional[str]` — The ID of the specific redirect rule + +
+
+ +
+
+ +**from_url:** `typing.Optional[str]` — The source URL path that will be redirected. + +
+
+ +
+
+ +**to_url:** `typing.Optional[str]` — The target URL path where the user or client will be redirected. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.sites.redirects.delete(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Remove a 301 redirection rule from a site. + +This is useful for cleaning up outdated or unnecessary redirects, ensuring that your site's routing behavior remains efficient and up-to-date. + +This endpoint requires an Enterprise workspace. + +Required scope: `sites:write` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.redirects.delete( + site_id="580e63e98c9a982ac9b8b741", + redirect_id="66c4cb9a20cac35ed19500e6", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**redirect_id:** `str` — Unique identifier site rediect + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.sites.redirects.update(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Update a 301 redirection rule from a site. + +This endpoint requires an Enterprise workspace. + +Required scope: `sites:write` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.redirects.update( + site_id="580e63e98c9a982ac9b8b741", + redirect_id="66c4cb9a20cac35ed19500e6", + id="42e1a2b7aa1a13f768a0042a", + from_url="/mostly-harmless", + to_url="/earth", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**redirect_id:** `str` — Unique identifier site rediect + +
+
+ +
+
+ +**id:** `typing.Optional[str]` — The ID of the specific redirect rule + +
+
+ +
+
+ +**from_url:** `typing.Optional[str]` — The source URL path that will be redirected. + +
+
+ +
+
+ +**to_url:** `typing.Optional[str]` — The target URL path where the user or client will be redirected. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Sites Plans +
client.sites.plans.get_site_plan(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get site plan details for the specified Site. + +This endpoint requires an Enterprise workspace. + +Required scope | `sites:read` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.plans.get_site_plan( + site_id="580e63e98c9a982ac9b8b741", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Sites RobotsTxt +
client.sites.robots_txt.get(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieve the robots.txt configuration for various user agents. + +This endpoint requires an Enterprise workspace. + +Required scope: `site_config:read` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.robots_txt.get( + site_id="580e63e98c9a982ac9b8b741", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.sites.robots_txt.put(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Replace the `robots.txt` configuration for various user agents. + +This endpoint requires an Enterprise workspace. + +Required scope | `site_config:write` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import RobotsRulesItem, Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.robots_txt.put( + site_id="580e63e98c9a982ac9b8b741", + rules=[ + RobotsRulesItem( + user_agent="googlebot", + allows=["/public"], + disallows=["/vogon-poetry", "/total-perspective-vortex"], + ) + ], + sitemap="https://heartofgold.ship/sitemap.xml", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**rules:** `typing.Optional[typing.Sequence[RobotsRulesItem]]` — List of rules for user agents. + +
+
+ +
+
+ +**sitemap:** `typing.Optional[str]` — URL to the sitemap. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.sites.robots_txt.delete(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Remove specific rules for a user-agent in your `robots.txt` file. To delete all rules for a user-agent, provide an empty rule set. This will remove the user-agent's entry entirely, leaving it subject to your site's default crawling behavior. + +**Note:** Deleting a user-agent with no rules will make the user-agent's access unrestricted unless other directives apply. + +This endpoint requires an Enterprise workspace. + +Required scope: `site_config:write` +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from webflow import RobotsRulesItem, Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.robots_txt.delete( + site_id="580e63e98c9a982ac9b8b741", + rules=[ + RobotsRulesItem( + user_agent="*", + allows=["/public"], + disallows=["/bubbles"], + ) + ], +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**rules:** `typing.Optional[typing.Sequence[RobotsRulesItem]]` — List of rules for user agents.
@@ -7612,7 +8751,7 @@ client.collections.items.get_item_live(
-**cms_locale_id:** `typing.Optional[str]` — Unique identifier for a CMS Locale. This UID is different from the Site locale identifier and is listed as `cmsLocaleId` in the Sites response. To query multiple locales, input a comma separated string. +**sitemap:** `typing.Optional[str]` — URL to the sitemap.
@@ -7632,7 +8771,7 @@ client.collections.items.get_item_live(
-
client.collections.items.delete_item_live(...) +
client.sites.robots_txt.patch(...)
@@ -7644,11 +8783,11 @@ client.collections.items.get_item_live(
-Remove a live item from the site. Removing a published item will unpublish the item from the live site and set it to draft. +Update the `robots.txt` configuration for various user agents. -This endpoint does not currently support bulk deletion. +This endpoint requires an Enterprise workspace. -Required scope | `CMS:write` +Required scope | `site_config:write`
@@ -7663,14 +8802,21 @@ Required scope | `CMS:write`
```python -from webflow import Webflow +from webflow import RobotsRulesItem, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.collections.items.delete_item_live( - collection_id="580e63fc8c9a982ac9b8b745", - item_id="580e64008c9a982ac9b8b754", +client.sites.robots_txt.patch( + site_id="580e63e98c9a982ac9b8b741", + rules=[ + RobotsRulesItem( + user_agent="googlebot", + allows=["/public"], + disallows=["/vogon-poetry", "/total-perspective-vortex"], + ) + ], + sitemap="https://heartofgold.ship/sitemap.xml", ) ``` @@ -7687,7 +8833,7 @@ client.collections.items.delete_item_live(
-**collection_id:** `str` — Unique identifier for a Collection +**site_id:** `str` — Unique identifier for a Site
@@ -7695,7 +8841,7 @@ client.collections.items.delete_item_live(
-**item_id:** `str` — Unique identifier for an Item +**rules:** `typing.Optional[typing.Sequence[RobotsRulesItem]]` — List of rules for user agents.
@@ -7703,7 +8849,7 @@ client.collections.items.delete_item_live(
-**cms_locale_id:** `typing.Optional[str]` — Unique identifier for a CMS Locale. This UID is different from the Site locale identifier and is listed as `cmsLocaleId` in the Sites response. To query multiple locales, input a comma separated string. +**sitemap:** `typing.Optional[str]` — URL to the sitemap.
@@ -7723,7 +8869,8 @@ client.collections.items.delete_item_live(
-
client.collections.items.update_item_live(...) +## Sites WellKnown +
client.sites.well_known.put(...)
@@ -7735,9 +8882,20 @@ client.collections.items.delete_item_live(
-Update a selected live Item in a Collection. The updates for this Item will be published to the live site. +Upload a supported well-known file to a site. -Required scope | `CMS:write` +The current restrictions on well-known files are as follows: + - Each file must be smaller than 100kb + - Less than 30 total files + - Have one of the following file extensions (or no extension): `.txt`, `.json`, `.noext` + + + `.noext` is a special file extension that removes other extensions. For example, `apple-app-site-association.noext.txt` will be uploaded as `apple-app-site-association`. Use this extension for tools that have trouble uploading extensionless files. + + +This endpoint requires an Enterprise workspace. + +Required scope: `site_config:write`
@@ -7752,20 +8910,16 @@ Required scope | `CMS:write`
```python -from webflow import CollectionItemPatchSingleFieldData, Webflow +from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.collections.items.update_item_live( - collection_id="580e63fc8c9a982ac9b8b745", - item_id="580e64008c9a982ac9b8b754", - is_archived=False, - is_draft=False, - field_data=CollectionItemPatchSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", - ), +client.sites.well_known.put( + site_id="580e63e98c9a982ac9b8b741", + file_name="apple-app-site-association.txt", + file_data='{\n "applinks": {\n "apps": [],\n "details": [\n {\n "appID": "ABCDE12345.com.example.app",\n "paths": [ "/*", "/some/path/*" ]\n }\n ]\n }\n}\n', + content_type="application/json", ) ``` @@ -7782,7 +8936,7 @@ client.collections.items.update_item_live(
-**collection_id:** `str` — Unique identifier for a Collection +**site_id:** `str` — Unique identifier for a Site
@@ -7790,7 +8944,7 @@ client.collections.items.update_item_live(
-**item_id:** `str` — Unique identifier for an Item +**file_name:** `str` — The name of the file
@@ -7798,7 +8952,7 @@ client.collections.items.update_item_live(
-**id:** `typing.Optional[str]` — Unique identifier for the Item +**file_data:** `str` — The contents of the file
@@ -7806,7 +8960,7 @@ client.collections.items.update_item_live(
-**cms_locale_id:** `typing.Optional[str]` — Identifier for the locale of the CMS item +**content_type:** `typing.Optional[WellKnownFileContentType]` — The content type of the file. Defaults to application/json
@@ -7814,39 +8968,73 @@ client.collections.items.update_item_live(
-**last_published:** `typing.Optional[str]` — The date the item was last published +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
-
-
-**last_updated:** `typing.Optional[str]` — The date the item was last updated -
+
+
client.sites.well_known.delete(...)
-**created_on:** `typing.Optional[str]` — The date the item was created - +#### 📝 Description + +
+
+ +
+
+ +Delete existing well-known files from a site. + +This endpoint requires an Enterprise workspace. + +Required scope: `site_config:write`
+
+
+ +#### 🔌 Usage
-**is_archived:** `typing.Optional[bool]` — Boolean determining if the Item is set to archived - +
+
+ +```python +from webflow import Webflow + +client = Webflow( + access_token="YOUR_ACCESS_TOKEN", +) +client.sites.well_known.delete( + site_id="580e63e98c9a982ac9b8b741", +) + +``` +
+
+#### ⚙️ Parameters +
-**is_draft:** `typing.Optional[bool]` — Boolean determining if the Item is set to draft +
+
+ +**site_id:** `str` — Unique identifier for a Site
@@ -7854,7 +9042,7 @@ client.collections.items.update_item_live(
-**field_data:** `typing.Optional[CollectionItemPatchSingleFieldData]` +**file_names:** `typing.Optional[typing.Sequence[str]]` — A list of file names to delete
@@ -7874,7 +9062,8 @@ client.collections.items.update_item_live(
-
client.collections.items.publish_item(...) +## Sites ActivityLogs +
client.sites.activity_logs.list(...)
@@ -7886,9 +9075,11 @@ client.collections.items.update_item_live(
-Publish an item or multiple items. +Retrieve Activity Logs for a specific Site. -Required scope | `cms:write` +This endpoint requires an Enterprise workspace. + +Required scope: `site_activity:read`
@@ -7908,9 +9099,10 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.collections.items.publish_item( - collection_id="580e63fc8c9a982ac9b8b745", - item_ids=["itemIds"], +client.sites.activity_logs.list( + site_id="580e63e98c9a982ac9b8b741", + limit=1, + offset=1, ) ``` @@ -7927,7 +9119,15 @@ client.collections.items.publish_item(
-**collection_id:** `str` — Unique identifier for a Collection +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100)
@@ -7935,7 +9135,7 @@ client.collections.items.publish_item(
-**item_ids:** `typing.Sequence[str]` +**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records
@@ -7955,8 +9155,8 @@ client.collections.items.publish_item(
-## Pages Scripts -
client.pages.scripts.get_custom_code(...) +## Sites Comments +
client.sites.comments.list_comment_threads(...)
@@ -7968,15 +9168,13 @@ client.collections.items.publish_item(
-Get all registered scripts that have been applied to a specific Page. +List all comment threads for a site. -In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered -to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate -`custom_code` endpoints. - -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + There may be a delay of up to 5 minutes before new comments appear in the system. + -Required scope | `custom_code:read` +Required scope | `comments:read`
@@ -7996,8 +9194,13 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.pages.scripts.get_custom_code( - page_id="63c720f9347c2139b248e552", +client.sites.comments.list_comment_threads( + site_id="580e63e98c9a982ac9b8b741", + locale_id="65427cf400e02b306eaa04a0", + offset=1, + limit=1, + sort_by="createdOn", + sort_order="asc", ) ``` @@ -8014,7 +9217,51 @@ client.pages.scripts.get_custom_code(
-**page_id:** `str` — Unique identifier for a Page +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + +
+
+ +
+
+ +**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100) + +
+
+ +
+
+ +**sort_by:** `typing.Optional[CommentsListCommentThreadsRequestSortBy]` — Sort results by the provided value. Only allowed when sortOrder is provided. + +
+
+ +
+
+ +**sort_order:** `typing.Optional[CommentsListCommentThreadsRequestSortOrder]` — Sorts the results by asc or desc
@@ -8034,7 +9281,7 @@ client.pages.scripts.get_custom_code(
-
client.pages.scripts.upsert_custom_code(...) +
client.sites.comments.get_comment_thread(...)
@@ -8046,17 +9293,13 @@ client.pages.scripts.get_custom_code(
-Add a registered script to a Page. - -In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered -to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate -`custom_code` endpoints. - -A site can have a maximum of 800 registered scripts. +Get details of a specific comment thread. -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + There may be a delay of up to 5 minutes before new comments appear in the system. + -Required scope | `custom_code:write` +Required scope | `comments:read`
@@ -8071,26 +9314,19 @@ Required scope | `custom_code:write`
```python -from webflow import ScriptApply, Webflow +from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.pages.scripts.upsert_custom_code( - page_id="63c720f9347c2139b248e552", - scripts=[ - ScriptApply( - id="cms_slider", - location="header", - version="1.0.0", - attributes={"my-attribute": "some-value"}, - ), - ScriptApply( - id="alert", - location="header", - version="0.0.1", - ), - ], +client.sites.comments.get_comment_thread( + site_id="580e63e98c9a982ac9b8b741", + comment_thread_id="580e63e98c9a982ac9b8b741", + locale_id="65427cf400e02b306eaa04a0", + offset=1, + limit=1, + sort_by="createdOn", + sort_order="asc", ) ``` @@ -8107,7 +9343,7 @@ client.pages.scripts.upsert_custom_code(
-**page_id:** `str` — Unique identifier for a Page +**site_id:** `str` — Unique identifier for a Site
@@ -8115,7 +9351,7 @@ client.pages.scripts.upsert_custom_code(
-**scripts:** `typing.Optional[typing.Sequence[ScriptApply]]` — A list of scripts applied to a Site or a Page +**comment_thread_id:** `str` — Unique identifier for a Comment Thread
@@ -8123,7 +9359,11 @@ client.pages.scripts.upsert_custom_code(
-**last_updated:** `typing.Optional[str]` — Date when the Site's scripts were last updated +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization)
@@ -8131,7 +9371,31 @@ client.pages.scripts.upsert_custom_code(
-**created_on:** `typing.Optional[str]` — Date when the Site's scripts were created +**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100) + +
+
+ +
+
+ +**sort_by:** `typing.Optional[CommentsGetCommentThreadRequestSortBy]` — Sort results by the provided value. Only allowed when sortOrder is provided. + +
+
+ +
+
+ +**sort_order:** `typing.Optional[CommentsGetCommentThreadRequestSortOrder]` — Sorts the results by asc or desc
@@ -8151,7 +9415,7 @@ client.pages.scripts.upsert_custom_code(
-
client.pages.scripts.delete_custom_code(...) +
client.sites.comments.list_comment_replies(...)
@@ -8163,15 +9427,13 @@ client.pages.scripts.upsert_custom_code(
-Delete the custom code block that an app has created for a page +List all replies to a specific comment thread. -In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered -to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate -`custom_code` endpoints. - -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + There may be a delay of up to 5 minutes before new comments appear in the system. + -Required scope | `custom_code:write` +Required scope | `comments:read`
@@ -8191,8 +9453,14 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.pages.scripts.delete_custom_code( - page_id="63c720f9347c2139b248e552", +client.sites.comments.list_comment_replies( + site_id="580e63e98c9a982ac9b8b741", + comment_thread_id="580e63e98c9a982ac9b8b741", + locale_id="65427cf400e02b306eaa04a0", + offset=1, + limit=1, + sort_by="createdOn", + sort_order="asc", ) ``` @@ -8209,7 +9477,59 @@ client.pages.scripts.delete_custom_code(
-**page_id:** `str` — Unique identifier for a Page +**site_id:** `str` — Unique identifier for a Site + +
+
+ +
+
+ +**comment_thread_id:** `str` — Unique identifier for a Comment Thread + +
+
+ +
+
+ +**locale_id:** `typing.Optional[str]` + +Unique identifier for a specific Locale. + +[Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + +
+
+ +
+
+ +**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100) + +
+
+ +
+
+ +**sort_by:** `typing.Optional[CommentsListCommentRepliesRequestSortBy]` — Sort results by the provided value. Only allowed when sortOrder is provided. + +
+
+ +
+
+ +**sort_order:** `typing.Optional[CommentsListCommentRepliesRequestSortOrder]` — Sorts the results by asc or desc
@@ -8229,8 +9549,8 @@ client.pages.scripts.delete_custom_code(
-## Sites Redirects -
client.sites.redirects.list(...) +## Sites Scripts +
client.sites.scripts.get_custom_code(...)
@@ -8242,12 +9562,13 @@ client.pages.scripts.delete_custom_code(
-Fetch a list of all URL redirect rules configured for a specific site. - -Use this endpoint to review, audit, or manage the redirection rules that control how traffic is rerouted on your site. +Get all scripts applied to a site by the App. + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + -Required scope: `sites:read` +Required scope | `custom_code:read`
@@ -8267,7 +9588,7 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.sites.redirects.list( +client.sites.scripts.get_custom_code( site_id="580e63e98c9a982ac9b8b741", ) @@ -8305,7 +9626,7 @@ client.sites.redirects.list(
-
client.sites.redirects.create(...) +
client.sites.scripts.upsert_custom_code(...)
@@ -8317,11 +9638,13 @@ client.sites.redirects.list(
-Add a new URL redirection rule to a site. +Apply registered scripts to a site. If you have multiple scripts your App needs to apply or maintain on a site, ensure they are always included in the request body for this endpoint. To remove individual scripts, simply call this endpoint without the script in the request body. -This endpoint allows you to define a source path (`fromUrl`) and its corresponding destination path (`toUrl`), which will dictate how traffic is rerouted on your site. This is useful for managing site changes, restructuring URLs, or handling outdated links. + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + -Required scope: `sites:write` +Required scope | `custom_code:write`
@@ -8336,16 +9659,26 @@ Required scope: `sites:write`
```python -from webflow import Webflow +from webflow import ScriptApply, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.sites.redirects.create( +client.sites.scripts.upsert_custom_code( site_id="580e63e98c9a982ac9b8b741", - id="42e1a2b7aa1a13f768a0042a", - from_url="/mostly-harmless", - to_url="/earth", + scripts=[ + ScriptApply( + id="cms_slider", + location="header", + version="1.0.0", + attributes={"my-attribute": "some-value"}, + ), + ScriptApply( + id="alert", + location="header", + version="0.0.1", + ), + ], ) ``` @@ -8370,7 +9703,7 @@ client.sites.redirects.create(
-**id:** `typing.Optional[str]` — The ID of the specific redirect rule +**scripts:** `typing.Optional[typing.Sequence[ScriptApply]]` — A list of scripts applied to a Site or a Page
@@ -8378,7 +9711,7 @@ client.sites.redirects.create(
-**from_url:** `typing.Optional[str]` — The source URL path that will be redirected. +**last_updated:** `typing.Optional[str]` — Date when the Site's scripts were last updated
@@ -8386,7 +9719,7 @@ client.sites.redirects.create(
-**to_url:** `typing.Optional[str]` — The target URL path where the user or client will be redirected. +**created_on:** `typing.Optional[str]` — Date when the Site's scripts were created
@@ -8406,7 +9739,7 @@ client.sites.redirects.create(
-
client.sites.redirects.delete(...) +
client.sites.scripts.delete_custom_code(...)
@@ -8418,9 +9751,13 @@ client.sites.redirects.create(
-Remove a URL redirection rule from a site. -This is useful for cleaning up outdated or unnecessary redirects, ensuring that your site's routing behavior remains efficient and up-to-date. -Required scope: `sites:write` +Remove all scripts from a site applied by the App. This endpoint will not remove scripts from the site's registered scripts. + +To remove individual scripts applied by the App, use the [Add/Update Custom Code](/data/reference/custom-code/custom-code-sites/upsert-custom-code) endpoint. + +Access to this endpoint requires a bearer token obtained from an [OAuth Code Grant Flow](/data/reference/oauth-app). + +Required scope | `custom_code:write`
@@ -8440,9 +9777,8 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.sites.redirects.delete( +client.sites.scripts.delete_custom_code( site_id="580e63e98c9a982ac9b8b741", - redirect_id="66c4cb9a20cac35ed19500e6", ) ``` @@ -8467,14 +9803,6 @@ client.sites.redirects.delete(
-**redirect_id:** `str` — Unique identifier site rediect - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -8487,7 +9815,7 @@ client.sites.redirects.delete(
-
client.sites.redirects.update(...) +
client.sites.scripts.list_custom_code_blocks(...)
@@ -8499,8 +9827,15 @@ client.sites.redirects.delete(
-Update a URL redirection rule from a site. -Required scope: `sites:write` +Get a list of scripts that have been applied to a site and/or individual pages. + + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. + + See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + + +Required scope | `custom_code:read`
@@ -8520,12 +9855,10 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.sites.redirects.update( +client.sites.scripts.list_custom_code_blocks( site_id="580e63e98c9a982ac9b8b741", - redirect_id="66c4cb9a20cac35ed19500e6", - id="42e1a2b7aa1a13f768a0042a", - from_url="/mostly-harmless", - to_url="/earth", + offset=1, + limit=1, ) ``` @@ -8550,23 +9883,7 @@ client.sites.redirects.update(
-**redirect_id:** `str` — Unique identifier site rediect - -
-
- -
-
- -**id:** `typing.Optional[str]` — The ID of the specific redirect rule - -
-
- -
-
- -**from_url:** `typing.Optional[str]` — The source URL path that will be redirected. +**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records
@@ -8574,7 +9891,7 @@ client.sites.redirects.update(
-**to_url:** `typing.Optional[str]` — The target URL path where the user or client will be redirected. +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100)
@@ -8594,8 +9911,8 @@ client.sites.redirects.update(
-## Sites Plans -
client.sites.plans.get_site_plan(...) +## Sites Forms +
client.sites.forms.list_submissions_by_site(...)
@@ -8607,9 +9924,17 @@ client.sites.redirects.update(
-Get site plan details for the specified Site. +List all form submissions for a given site with the ability to filter submissions by a centralized `elementId`. -Required scope | `sites:read` +Add `elementId` when you want to filter form submissions to a specific form in a site. You can get the `elementId` from the [List forms endpoint](/data/reference/forms/forms/list) (displayed as `formElementId` in the response). + + +When a form is used in a Webflow component definition, each instance of the component will yield a unique form. Adding the `elementId` in this request ensures this API response includes all submissions from that core form, wherever that form is used in instantiated components. + + +Use the [List Form Submissions endpoint](/data/reference/forms/form-submissions/list-submissions) to list form submissions for a given form ID. + +Required scope | `forms:read`
@@ -8629,8 +9954,11 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.sites.plans.get_site_plan( +client.sites.forms.list_submissions_by_site( site_id="580e63e98c9a982ac9b8b741", + element_id="18259716-3e5a-646a-5f41-5dc4b9405aa0", + offset=1, + limit=1, ) ``` @@ -8655,6 +9983,30 @@ client.sites.plans.get_site_plan(
+**element_id:** `typing.Optional[str]` — Identifier for an element + +
+
+ +
+
+ +**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100) + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -8667,8 +10019,7 @@ client.sites.plans.get_site_plan(
-## Sites ActivityLogs -
client.sites.activity_logs.list(...) +
client.sites.forms.list_submissions(...)
@@ -8680,7 +10031,11 @@ client.sites.plans.get_site_plan(
-Retrieve Activity Logs for a specific Site. Requires Site to be on an Enterprise plan.

Required scope | `site_activity:read` +List form submissions for a given form ID within a specific site. + +Use the [List Form Submissions by Site endpoint](/data/reference/forms/form-submissions/list-submissions-by-site) to list form submissions for a given site with the ability to filter by a `formElementId`. + +Required scope | `forms:read`
@@ -8700,8 +10055,11 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.sites.activity_logs.list( +client.sites.forms.list_submissions( site_id="580e63e98c9a982ac9b8b741", + form_id="580e63e98c9a982ac9b8b741", + offset=1, + limit=1, ) ``` @@ -8726,7 +10084,15 @@ client.sites.activity_logs.list(
-**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) +**form_id:** `str` — Unique identifier for a Form + +
+
+ +
+
+ +**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records
@@ -8734,7 +10100,7 @@ client.sites.activity_logs.list(
-**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100)
@@ -8754,8 +10120,7 @@ client.sites.activity_logs.list(
-## Sites Scripts -
client.sites.scripts.get_custom_code(...) +
client.sites.forms.get_submission(...)
@@ -8767,11 +10132,9 @@ client.sites.activity_logs.list(
-Get all registered scripts that have been applied to a specific Site. +Get information about a form submission within a specific site. -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). - -Required scope | `custom_code:read` +Required scope | `forms:read`
@@ -8791,8 +10154,9 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.sites.scripts.get_custom_code( +client.sites.forms.get_submission( site_id="580e63e98c9a982ac9b8b741", + form_submission_id="580e63e98c9a982ac9b8b741", ) ``` @@ -8817,6 +10181,14 @@ client.sites.scripts.get_custom_code(
+**form_submission_id:** `str` — Unique identifier for a Form Submission + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -8829,7 +10201,7 @@ client.sites.scripts.get_custom_code(
-
client.sites.scripts.upsert_custom_code(...) +
client.sites.forms.delete_submission(...)
@@ -8841,15 +10213,9 @@ client.sites.scripts.get_custom_code(
-Add a registered script to a Site. - -In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered -to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate -`custom_code` endpoints. - -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). +Delete a form submission within a specific site. -Required scope | `custom_code:write` +Required scope | `forms:write`
@@ -8864,26 +10230,14 @@ Required scope | `custom_code:write`
```python -from webflow import ScriptApply, Webflow +from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.sites.scripts.upsert_custom_code( +client.sites.forms.delete_submission( site_id="580e63e98c9a982ac9b8b741", - scripts=[ - ScriptApply( - id="cms_slider", - location="header", - version="1.0.0", - attributes={"my-attribute": "some-value"}, - ), - ScriptApply( - id="alert", - location="header", - version="0.0.1", - ), - ], + form_submission_id="580e63e98c9a982ac9b8b741", ) ``` @@ -8908,23 +10262,7 @@ client.sites.scripts.upsert_custom_code(
-**scripts:** `typing.Optional[typing.Sequence[ScriptApply]]` — A list of scripts applied to a Site or a Page - -
-
- -
-
- -**last_updated:** `typing.Optional[str]` — Date when the Site's scripts were last updated - -
-
- -
-
- -**created_on:** `typing.Optional[str]` — Date when the Site's scripts were created +**form_submission_id:** `str` — Unique identifier for a Form Submission
@@ -8944,7 +10282,7 @@ client.sites.scripts.upsert_custom_code(
-
client.sites.scripts.delete_custom_code(...) +
client.sites.forms.update_submission(...)
@@ -8956,11 +10294,9 @@ client.sites.scripts.upsert_custom_code(
-Delete the custom code block that an app created for a Site +Update hidden fields on a form submission within a specific site. -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). - -Required scope | `custom_code:write` +Required scope | `forms:write`
@@ -8980,8 +10316,9 @@ from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.sites.scripts.delete_custom_code( +client.sites.forms.update_submission( site_id="580e63e98c9a982ac9b8b741", + form_submission_id="580e63e98c9a982ac9b8b741", ) ``` @@ -9006,6 +10343,22 @@ client.sites.scripts.delete_custom_code(
+**form_submission_id:** `str` — Unique identifier for a Form Submission + +
+
+ +
+
+ +**form_submission_data:** `typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]` — An existing **hidden field** defined on the form schema, and the corresponding value to set + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -9018,7 +10371,8 @@ client.sites.scripts.delete_custom_code(
-
client.sites.scripts.list_custom_code_blocks(...) +## Workspaces AuditLogs +
client.workspaces.audit_logs.get_workspace_audit_logs(...)
@@ -9030,11 +10384,11 @@ client.sites.scripts.delete_custom_code(
-Get all instances of Custom Code applied to a Site or Pages. +Get audit logs for a workspace. -Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). +This endpoint requires an Enterprise workspace and a workspace token with the `workspace_activity:read` scope. Create a workspace token from your workspace dashboard integrations page to use this endpoint. -Required scope | `custom_code:read` +Required scope | `workspace_activity:read`
@@ -9049,13 +10403,25 @@ Required scope | `custom_code:read`
```python +import datetime + from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) -client.sites.scripts.list_custom_code_blocks( - site_id="580e63e98c9a982ac9b8b741", +client.workspaces.audit_logs.get_workspace_audit_logs( + workspace_id_or_slug="hitchhikers-workspace", + limit=1, + offset=1, + sort_order="asc", + event_type="user_access", + from_=datetime.datetime.fromisoformat( + "2025-06-22 16:00:31+00:00", + ), + to=datetime.datetime.fromisoformat( + "2025-07-22 16:00:31+00:00", + ), ) ``` @@ -9072,7 +10438,39 @@ client.sites.scripts.list_custom_code_blocks(
-**site_id:** `str` — Unique identifier for a Site +**workspace_id_or_slug:** `str` — Unique identifier or slug for a Workspace + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Maximum number of records to be returned (max limit: 100) + +
+
+ +
+
+ +**offset:** `typing.Optional[int]` — Offset used for pagination if the results have more than limit records + +
+
+ +
+
+ +**sort_order:** `typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestSortOrder]` — Sorts the results by asc or desc + +
+
+ +
+
+ +**event_type:** `typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestEventType]` — The event type to filter by
@@ -9080,7 +10478,7 @@ client.sites.scripts.list_custom_code_blocks(
-**offset:** `typing.Optional[float]` — Offset used for pagination if the results have more than limit records +**from_:** `typing.Optional[dt.datetime]` — The start date to filter by
@@ -9088,7 +10486,7 @@ client.sites.scripts.list_custom_code_blocks(
-**limit:** `typing.Optional[float]` — Maximum number of records to be returned (max limit: 100) +**to:** `typing.Optional[dt.datetime]` — The end date to filter by
diff --git a/src/webflow/__init__.py b/src/webflow/__init__.py index 0d82d59..4c00894 100644 --- a/src/webflow/__init__.py +++ b/src/webflow/__init__.py @@ -1,8 +1,6 @@ # This file was auto-generated by Fern from our API Definition. from .types import ( - AccessGroup, - AccessGroupList, Application, Asset, AssetFolder, @@ -20,6 +18,8 @@ BulkCollectionItemFieldData, Collection, CollectionItem, + CollectionItemChanged, + CollectionItemCreated, CollectionItemFieldData, CollectionItemList, CollectionItemListNoPagination, @@ -28,10 +28,31 @@ CollectionItemPatchSingleFieldData, CollectionItemPostSingle, CollectionItemPostSingleFieldData, + CollectionItemPublished, + CollectionItemRemoved, + CollectionItemRemovedPayload, + CollectionItemRemovedPayloadFieldData, + CollectionItemUnpublished, + CollectionItemUnpublishedPayload, + CollectionItemUnpublishedPayloadFieldData, CollectionItemWithIdInput, CollectionItemWithIdInputFieldData, CollectionList, CollectionListArrayItem, + Comment, + CommentPayload, + CommentPayloadAuthor, + CommentPayloadMentionedUsersItem, + CommentReply, + CommentReplyAuthor, + CommentReplyList, + CommentReplyListPagination, + CommentReplyMentionedUsersItem, + CommentThread, + CommentThreadAuthor, + CommentThreadList, + CommentThreadListPagination, + CommentThreadMentionedUsersItem, Component, ComponentDom, ComponentInstanceNodePropertyOverridesWrite, @@ -41,20 +62,26 @@ ComponentProperties, ComponentProperty, ComponentPropertyType, - ConflictErrorBody, + Conflict, CustomCodeBlock, CustomCodeBlockType, CustomCodeHostedResponse, CustomCodeInlineResponse, + CustomRole, + CustomRoleAuditLogItem, + CustomRoleAuditLogItemEventSubType, Dom, Domain, Domains, - DuplicateUserEmail, EcommerceSettings, Error, ErrorCode, Field, + FieldCreate, FieldType, + FieldValidations, + FieldValidationsAdditionalProperties, + FieldValidationsAdditionalPropertiesAdditionalProperties, ForbiddenErrorBody, Form, FormField, @@ -64,26 +91,43 @@ FormResponseSettings, FormSubmission, FormSubmissionList, + FormSubmissionTrigger, + FormSubmissionTriggerPayload, + FormSubmissionTriggerPayloadSchemaItem, + FormSubmissionTriggerPayloadSchemaItemFieldType, ImageNode, ImageNodeImage, InvalidDomain, InvalidScopes, InventoryItem, InventoryItemInventoryType, + ItemsListItemsLiveRequestLastPublished, + ItemsListItemsRequestLastPublished, ListCustomCodeBlocks, Locale, Locales, + Metadata, + MetadataOptionsItem, + NewOrder, NoDomains, Node, Node_ComponentInstance, Node_Image, + Node_SearchButton, + Node_Select, + Node_SubmitButton, Node_Text, + Node_TextInput, NotEnterprisePlanSite, NotEnterprisePlanWorkspace, + OptionField, Order, OrderAddress, OrderAddressJapanType, OrderAddressType, + OrderBillingAddress, + OrderBillingAddressJapanType, + OrderBillingAddressType, OrderCustomerInfo, OrderDisputeLastStatus, OrderDownloadFilesItem, @@ -94,15 +138,26 @@ OrderPurchasedItemVariantImage, OrderPurchasedItemVariantImageFile, OrderPurchasedItemVariantImageFileVariantsItem, + OrderShippingAddress, + OrderShippingAddressJapanType, + OrderShippingAddressType, OrderStatus, OrderTotals, OrderTotalsExtrasItem, OrderTotalsExtrasItemType, Page, + PageCreatedWebhook, + PageCreatedWebhookPayload, + PageDeletedWebhook, + PageDeletedWebhookPayload, PageList, + PageMetadataUpdatedWebhook, + PageMetadataUpdatedWebhookPayload, PageOpenGraph, PageSeo, Pagination, + Payload, + PayloadFieldData, PaypalDetails, Product, ProductAndSkUs, @@ -113,11 +168,26 @@ PublishStatus, Redirect, Redirects, + ReferenceField, + ReferenceFieldMetadata, + ReferenceFieldType, RegisteredScriptList, + Robots, + RobotsRulesItem, ScriptApply, ScriptApplyList, ScriptApplyLocation, Scripts, + SearchButtonNode, + SearchButtonNodeWrite, + Select, + SelectNode, + SelectNodeChoicesItem, + SelectNodeWriteChoicesItem, + SettingChange, + SettingChangeAuditLogItem, + SingleLocaleCreatedPayload, + SingleLocaleCreatedPayloadFieldData, Site, SiteActivityLogItem, SiteActivityLogItemEvent, @@ -125,9 +195,14 @@ SiteActivityLogItemUser, SiteActivityLogResponse, SiteDataCollectionType, + SiteMembership, + SiteMembershipAuditLogItem, + SiteMembershipAuditLogItemEventSubType, SitePlan, SitePlanId, SitePlanName, + SitePublish, + SitePublishPayload, Sites, Sku, SkuFieldData, @@ -141,27 +216,58 @@ SkuPropertyList, SkuPropertyListEnumItem, SkuValueList, + StaticField, + StaticFieldType, StripeCard, StripeCardBrand, StripeCardExpires, StripeDetails, + SubmitButtonNode, + SubmitButtonNodeWrite, Text, + TextInputNode, + TextInputNodeWrite, TextNode, TextNodeText, TextNodeWrite, TriggerType, - User, - UserAccessGroupsItem, - UserAccessGroupsItemType, - UserData, - UserDataData, - UserLimitReached, - UserList, - UserStatus, - UsersNotEnabled, + UpdatedOrder, + UserAccess, + UserAccessAuditLogItem, + UserAccessAuditLogItemEventSubType, Webhook, WebhookFilter, WebhookList, + WorkspaceAuditLogItem, + WorkspaceAuditLogItemActor, + WorkspaceAuditLogItemPayloadSettingChangeMethod, + WorkspaceAuditLogItemPayloadSiteMembershipGranularAccess, + WorkspaceAuditLogItemPayloadSiteMembershipMethod, + WorkspaceAuditLogItemPayloadSiteMembershipSite, + WorkspaceAuditLogItemPayloadSiteMembershipTargetUser, + WorkspaceAuditLogItemPayloadSiteMembershipUserType, + WorkspaceAuditLogItemPayloadUserAccessMethod, + WorkspaceAuditLogItemPayloadWorkspaceInvitationMethod, + WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUser, + WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUsersItem, + WorkspaceAuditLogItemPayloadWorkspaceInvitationUserType, + WorkspaceAuditLogItemPayloadWorkspaceMembershipMethod, + WorkspaceAuditLogItemPayloadWorkspaceMembershipTargetUser, + WorkspaceAuditLogItemPayloadWorkspaceMembershipUserType, + WorkspaceAuditLogItemWorkspace, + WorkspaceAuditLogItem_CustomRole, + WorkspaceAuditLogItem_SiteMembership, + WorkspaceAuditLogItem_UserAccess, + WorkspaceAuditLogItem_WorkspaceInvitation, + WorkspaceAuditLogItem_WorkspaceMembership, + WorkspaceAuditLogItem_WorkspaceSetting, + WorkspaceAuditLogResponse, + WorkspaceInvitation, + WorkspaceInvitationAuditLogItem, + WorkspaceInvitationAuditLogItemEventSubType, + WorkspaceMembership, + WorkspaceMembershipAuditLogItem, + WorkspaceMembershipAuditLogItemEventSubType, ) from .errors import ( BadRequestError, @@ -173,21 +279,22 @@ UnauthorizedError, ) from .resources import ( - AccessGroupsListRequestSort, ComponentDomWriteNodesItem, ComponentPropertiesWritePropertiesItem, ComponentsUpdateContentResponse, ComponentsUpdatePropertiesResponse, + EcommInventoryChangedPayload, InventoryUpdateRequestInventoryType, OrdersListRequestStatus, OrdersRefundRequestReason, PageDomWriteNodesItem, + PageMetadataWriteOpenGraph, + PageMetadataWriteSeo, + ProductSkuCreateProduct, + ProductSkuCreateSku, ProductsCreateSkuResponse, SitesPublishResponse, UpdateStaticContentResponse, - UsersListRequestSort, - UsersUpdateRequestData, - access_groups, assets, collections, components, @@ -200,17 +307,14 @@ scripts, sites, token, - users, webhooks, + workspaces, ) from .client import AsyncWebflow, Webflow from .environment import WebflowEnvironment from .version import __version__ __all__ = [ - "AccessGroup", - "AccessGroupList", - "AccessGroupsListRequestSort", "Application", "Asset", "AssetFolder", @@ -230,6 +334,8 @@ "BulkCollectionItemFieldData", "Collection", "CollectionItem", + "CollectionItemChanged", + "CollectionItemCreated", "CollectionItemFieldData", "CollectionItemList", "CollectionItemListNoPagination", @@ -238,10 +344,31 @@ "CollectionItemPatchSingleFieldData", "CollectionItemPostSingle", "CollectionItemPostSingleFieldData", + "CollectionItemPublished", + "CollectionItemRemoved", + "CollectionItemRemovedPayload", + "CollectionItemRemovedPayloadFieldData", + "CollectionItemUnpublished", + "CollectionItemUnpublishedPayload", + "CollectionItemUnpublishedPayloadFieldData", "CollectionItemWithIdInput", "CollectionItemWithIdInputFieldData", "CollectionList", "CollectionListArrayItem", + "Comment", + "CommentPayload", + "CommentPayloadAuthor", + "CommentPayloadMentionedUsersItem", + "CommentReply", + "CommentReplyAuthor", + "CommentReplyList", + "CommentReplyListPagination", + "CommentReplyMentionedUsersItem", + "CommentThread", + "CommentThreadAuthor", + "CommentThreadList", + "CommentThreadListPagination", + "CommentThreadMentionedUsersItem", "Component", "ComponentDom", "ComponentDomWriteNodesItem", @@ -255,21 +382,28 @@ "ComponentPropertyType", "ComponentsUpdateContentResponse", "ComponentsUpdatePropertiesResponse", + "Conflict", "ConflictError", - "ConflictErrorBody", "CustomCodeBlock", "CustomCodeBlockType", "CustomCodeHostedResponse", "CustomCodeInlineResponse", + "CustomRole", + "CustomRoleAuditLogItem", + "CustomRoleAuditLogItemEventSubType", "Dom", "Domain", "Domains", - "DuplicateUserEmail", + "EcommInventoryChangedPayload", "EcommerceSettings", "Error", "ErrorCode", "Field", + "FieldCreate", "FieldType", + "FieldValidations", + "FieldValidationsAdditionalProperties", + "FieldValidationsAdditionalPropertiesAdditionalProperties", "ForbiddenError", "ForbiddenErrorBody", "Form", @@ -280,6 +414,10 @@ "FormResponseSettings", "FormSubmission", "FormSubmissionList", + "FormSubmissionTrigger", + "FormSubmissionTriggerPayload", + "FormSubmissionTriggerPayloadSchemaItem", + "FormSubmissionTriggerPayloadSchemaItemFieldType", "ImageNode", "ImageNodeImage", "InternalServerError", @@ -288,21 +426,34 @@ "InventoryItem", "InventoryItemInventoryType", "InventoryUpdateRequestInventoryType", + "ItemsListItemsLiveRequestLastPublished", + "ItemsListItemsRequestLastPublished", "ListCustomCodeBlocks", "Locale", "Locales", + "Metadata", + "MetadataOptionsItem", + "NewOrder", "NoDomains", "Node", "Node_ComponentInstance", "Node_Image", + "Node_SearchButton", + "Node_Select", + "Node_SubmitButton", "Node_Text", + "Node_TextInput", "NotEnterprisePlanSite", "NotEnterprisePlanWorkspace", "NotFoundError", + "OptionField", "Order", "OrderAddress", "OrderAddressJapanType", "OrderAddressType", + "OrderBillingAddress", + "OrderBillingAddressJapanType", + "OrderBillingAddressType", "OrderCustomerInfo", "OrderDisputeLastStatus", "OrderDownloadFilesItem", @@ -313,6 +464,9 @@ "OrderPurchasedItemVariantImage", "OrderPurchasedItemVariantImageFile", "OrderPurchasedItemVariantImageFileVariantsItem", + "OrderShippingAddress", + "OrderShippingAddressJapanType", + "OrderShippingAddressType", "OrderStatus", "OrderTotals", "OrderTotalsExtrasItem", @@ -320,11 +474,21 @@ "OrdersListRequestStatus", "OrdersRefundRequestReason", "Page", + "PageCreatedWebhook", + "PageCreatedWebhookPayload", + "PageDeletedWebhook", + "PageDeletedWebhookPayload", "PageDomWriteNodesItem", "PageList", + "PageMetadataUpdatedWebhook", + "PageMetadataUpdatedWebhookPayload", + "PageMetadataWriteOpenGraph", + "PageMetadataWriteSeo", "PageOpenGraph", "PageSeo", "Pagination", + "Payload", + "PayloadFieldData", "PaypalDetails", "Product", "ProductAndSkUs", @@ -332,15 +496,32 @@ "ProductFieldData", "ProductFieldDataEcProductType", "ProductFieldDataTaxCategory", + "ProductSkuCreateProduct", + "ProductSkuCreateSku", "ProductsCreateSkuResponse", "PublishStatus", "Redirect", "Redirects", + "ReferenceField", + "ReferenceFieldMetadata", + "ReferenceFieldType", "RegisteredScriptList", + "Robots", + "RobotsRulesItem", "ScriptApply", "ScriptApplyList", "ScriptApplyLocation", "Scripts", + "SearchButtonNode", + "SearchButtonNodeWrite", + "Select", + "SelectNode", + "SelectNodeChoicesItem", + "SelectNodeWriteChoicesItem", + "SettingChange", + "SettingChangeAuditLogItem", + "SingleLocaleCreatedPayload", + "SingleLocaleCreatedPayloadFieldData", "Site", "SiteActivityLogItem", "SiteActivityLogItemEvent", @@ -348,9 +529,14 @@ "SiteActivityLogItemUser", "SiteActivityLogResponse", "SiteDataCollectionType", + "SiteMembership", + "SiteMembershipAuditLogItem", + "SiteMembershipAuditLogItemEventSubType", "SitePlan", "SitePlanId", "SitePlanName", + "SitePublish", + "SitePublishPayload", "Sites", "SitesPublishResponse", "Sku", @@ -365,11 +551,17 @@ "SkuPropertyList", "SkuPropertyListEnumItem", "SkuValueList", + "StaticField", + "StaticFieldType", "StripeCard", "StripeCardBrand", "StripeCardExpires", "StripeDetails", + "SubmitButtonNode", + "SubmitButtonNodeWrite", "Text", + "TextInputNode", + "TextInputNodeWrite", "TextNode", "TextNodeText", "TextNodeWrite", @@ -377,24 +569,46 @@ "TriggerType", "UnauthorizedError", "UpdateStaticContentResponse", - "User", - "UserAccessGroupsItem", - "UserAccessGroupsItemType", - "UserData", - "UserDataData", - "UserLimitReached", - "UserList", - "UserStatus", - "UsersListRequestSort", - "UsersNotEnabled", - "UsersUpdateRequestData", + "UpdatedOrder", + "UserAccess", + "UserAccessAuditLogItem", + "UserAccessAuditLogItemEventSubType", "Webflow", "WebflowEnvironment", "Webhook", "WebhookFilter", "WebhookList", + "WorkspaceAuditLogItem", + "WorkspaceAuditLogItemActor", + "WorkspaceAuditLogItemPayloadSettingChangeMethod", + "WorkspaceAuditLogItemPayloadSiteMembershipGranularAccess", + "WorkspaceAuditLogItemPayloadSiteMembershipMethod", + "WorkspaceAuditLogItemPayloadSiteMembershipSite", + "WorkspaceAuditLogItemPayloadSiteMembershipTargetUser", + "WorkspaceAuditLogItemPayloadSiteMembershipUserType", + "WorkspaceAuditLogItemPayloadUserAccessMethod", + "WorkspaceAuditLogItemPayloadWorkspaceInvitationMethod", + "WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUser", + "WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUsersItem", + "WorkspaceAuditLogItemPayloadWorkspaceInvitationUserType", + "WorkspaceAuditLogItemPayloadWorkspaceMembershipMethod", + "WorkspaceAuditLogItemPayloadWorkspaceMembershipTargetUser", + "WorkspaceAuditLogItemPayloadWorkspaceMembershipUserType", + "WorkspaceAuditLogItemWorkspace", + "WorkspaceAuditLogItem_CustomRole", + "WorkspaceAuditLogItem_SiteMembership", + "WorkspaceAuditLogItem_UserAccess", + "WorkspaceAuditLogItem_WorkspaceInvitation", + "WorkspaceAuditLogItem_WorkspaceMembership", + "WorkspaceAuditLogItem_WorkspaceSetting", + "WorkspaceAuditLogResponse", + "WorkspaceInvitation", + "WorkspaceInvitationAuditLogItem", + "WorkspaceInvitationAuditLogItemEventSubType", + "WorkspaceMembership", + "WorkspaceMembershipAuditLogItem", + "WorkspaceMembershipAuditLogItemEventSubType", "__version__", - "access_groups", "assets", "collections", "components", @@ -407,6 +621,6 @@ "scripts", "sites", "token", - "users", "webhooks", + "workspaces", ] diff --git a/src/webflow/client.py b/src/webflow/client.py index 90c233d..6f76267 100644 --- a/src/webflow/client.py +++ b/src/webflow/client.py @@ -1,7 +1,7 @@ # This file was auto-generated by Fern from our API Definition. -import typing from .environment import WebflowEnvironment +import typing import httpx from .core.client_wrapper import SyncClientWrapper from .resources.token.client import TokenClient @@ -13,12 +13,11 @@ from .resources.assets.client import AssetsClient from .resources.webhooks.client import WebhooksClient from .resources.forms.client import FormsClient -from .resources.users.client import UsersClient -from .resources.access_groups.client import AccessGroupsClient from .resources.products.client import ProductsClient from .resources.orders.client import OrdersClient from .resources.inventory.client import InventoryClient from .resources.ecommerce.client import EcommerceClient +from .resources.workspaces.client import WorkspacesClient from .core.client_wrapper import AsyncClientWrapper from .resources.token.client import AsyncTokenClient from .resources.sites.client import AsyncSitesClient @@ -29,12 +28,11 @@ from .resources.assets.client import AsyncAssetsClient from .resources.webhooks.client import AsyncWebhooksClient from .resources.forms.client import AsyncFormsClient -from .resources.users.client import AsyncUsersClient -from .resources.access_groups.client import AsyncAccessGroupsClient from .resources.products.client import AsyncProductsClient from .resources.orders.client import AsyncOrdersClient from .resources.inventory.client import AsyncInventoryClient from .resources.ecommerce.client import AsyncEcommerceClient +from .resources.workspaces.client import AsyncWorkspacesClient class Webflow: @@ -43,19 +41,16 @@ class Webflow: Parameters ---------- - base_url : typing.Optional[str] - The base url to use for requests from the client. - environment : WebflowEnvironment The environment to use for requests from the client. from .environment import WebflowEnvironment - Defaults to WebflowEnvironment.DEFAULT + Defaults to WebflowEnvironment.DATA_API - access_token : typing.Union[str, typing.Callable[[], str]] + access_token : typing.Optional[typing.Union[str, typing.Callable[[], str]]] timeout : typing.Optional[float] The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced. @@ -77,16 +72,15 @@ class Webflow: def __init__( self, *, - base_url: typing.Optional[str] = None, - environment: WebflowEnvironment = WebflowEnvironment.DEFAULT, - access_token: typing.Union[str, typing.Callable[[], str]], + environment: WebflowEnvironment = WebflowEnvironment.DATA_API, + access_token: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None, timeout: typing.Optional[float] = None, follow_redirects: typing.Optional[bool] = True, httpx_client: typing.Optional[httpx.Client] = None, ): _defaulted_timeout = timeout if timeout is not None else 60 if httpx_client is None else None self._client_wrapper = SyncClientWrapper( - base_url=_get_base_url(base_url=base_url, environment=environment), + environment=environment, access_token=access_token, httpx_client=httpx_client if httpx_client is not None @@ -104,12 +98,11 @@ def __init__( self.assets = AssetsClient(client_wrapper=self._client_wrapper) self.webhooks = WebhooksClient(client_wrapper=self._client_wrapper) self.forms = FormsClient(client_wrapper=self._client_wrapper) - self.users = UsersClient(client_wrapper=self._client_wrapper) - self.access_groups = AccessGroupsClient(client_wrapper=self._client_wrapper) self.products = ProductsClient(client_wrapper=self._client_wrapper) self.orders = OrdersClient(client_wrapper=self._client_wrapper) self.inventory = InventoryClient(client_wrapper=self._client_wrapper) self.ecommerce = EcommerceClient(client_wrapper=self._client_wrapper) + self.workspaces = WorkspacesClient(client_wrapper=self._client_wrapper) class AsyncWebflow: @@ -118,19 +111,16 @@ class AsyncWebflow: Parameters ---------- - base_url : typing.Optional[str] - The base url to use for requests from the client. - environment : WebflowEnvironment The environment to use for requests from the client. from .environment import WebflowEnvironment - Defaults to WebflowEnvironment.DEFAULT + Defaults to WebflowEnvironment.DATA_API - access_token : typing.Union[str, typing.Callable[[], str]] + access_token : typing.Optional[typing.Union[str, typing.Callable[[], str]]] timeout : typing.Optional[float] The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced. @@ -152,16 +142,15 @@ class AsyncWebflow: def __init__( self, *, - base_url: typing.Optional[str] = None, - environment: WebflowEnvironment = WebflowEnvironment.DEFAULT, - access_token: typing.Union[str, typing.Callable[[], str]], + environment: WebflowEnvironment = WebflowEnvironment.DATA_API, + access_token: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None, timeout: typing.Optional[float] = None, follow_redirects: typing.Optional[bool] = True, httpx_client: typing.Optional[httpx.AsyncClient] = None, ): _defaulted_timeout = timeout if timeout is not None else 60 if httpx_client is None else None self._client_wrapper = AsyncClientWrapper( - base_url=_get_base_url(base_url=base_url, environment=environment), + environment=environment, access_token=access_token, httpx_client=httpx_client if httpx_client is not None @@ -179,18 +168,8 @@ def __init__( self.assets = AsyncAssetsClient(client_wrapper=self._client_wrapper) self.webhooks = AsyncWebhooksClient(client_wrapper=self._client_wrapper) self.forms = AsyncFormsClient(client_wrapper=self._client_wrapper) - self.users = AsyncUsersClient(client_wrapper=self._client_wrapper) - self.access_groups = AsyncAccessGroupsClient(client_wrapper=self._client_wrapper) self.products = AsyncProductsClient(client_wrapper=self._client_wrapper) self.orders = AsyncOrdersClient(client_wrapper=self._client_wrapper) self.inventory = AsyncInventoryClient(client_wrapper=self._client_wrapper) self.ecommerce = AsyncEcommerceClient(client_wrapper=self._client_wrapper) - - -def _get_base_url(*, base_url: typing.Optional[str] = None, environment: WebflowEnvironment) -> str: - if base_url is not None: - return base_url - elif environment is not None: - return environment.value - else: - raise Exception("Please pass in either base_url or environment to construct the client") + self.workspaces = AsyncWorkspacesClient(client_wrapper=self._client_wrapper) diff --git a/src/webflow/core/client_wrapper.py b/src/webflow/core/client_wrapper.py index a04487e..3849c42 100644 --- a/src/webflow/core/client_wrapper.py +++ b/src/webflow/core/client_wrapper.py @@ -1,6 +1,7 @@ # This file was auto-generated by Fern from our API Definition. import typing +from ..environment import WebflowEnvironment import httpx from .http_client import HttpClient from .http_client import AsyncHttpClient @@ -10,31 +11,33 @@ class BaseClientWrapper: def __init__( self, *, - access_token: typing.Union[str, typing.Callable[[], str]], - base_url: str, + access_token: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None, + environment: WebflowEnvironment, timeout: typing.Optional[float] = None, ): self._access_token = access_token - self._base_url = base_url + self._environment = environment self._timeout = timeout def get_headers(self) -> typing.Dict[str, str]: headers: typing.Dict[str, str] = { "X-Fern-Language": "Python", "X-Fern-SDK-Name": "webflow", - "X-Fern-SDK-Version": "2.0.0b2", + "X-Fern-SDK-Version": "1.2.1", } - headers["Authorization"] = f"Bearer {self._get_access_token()}" + access_token = self._get_access_token() + if access_token is not None: + headers["Authorization"] = f"Bearer {access_token}" return headers - def _get_access_token(self) -> str: - if isinstance(self._access_token, str): + def _get_access_token(self) -> typing.Optional[str]: + if isinstance(self._access_token, str) or self._access_token is None: return self._access_token else: return self._access_token() - def get_base_url(self) -> str: - return self._base_url + def get_environment(self) -> WebflowEnvironment: + return self._environment def get_timeout(self) -> typing.Optional[float]: return self._timeout @@ -44,17 +47,14 @@ class SyncClientWrapper(BaseClientWrapper): def __init__( self, *, - access_token: typing.Union[str, typing.Callable[[], str]], - base_url: str, + access_token: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None, + environment: WebflowEnvironment, timeout: typing.Optional[float] = None, httpx_client: httpx.Client, ): - super().__init__(access_token=access_token, base_url=base_url, timeout=timeout) + super().__init__(access_token=access_token, environment=environment, timeout=timeout) self.httpx_client = HttpClient( - httpx_client=httpx_client, - base_headers=self.get_headers, - base_timeout=self.get_timeout, - base_url=self.get_base_url, + httpx_client=httpx_client, base_headers=self.get_headers, base_timeout=self.get_timeout ) @@ -62,15 +62,12 @@ class AsyncClientWrapper(BaseClientWrapper): def __init__( self, *, - access_token: typing.Union[str, typing.Callable[[], str]], - base_url: str, + access_token: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None, + environment: WebflowEnvironment, timeout: typing.Optional[float] = None, httpx_client: httpx.AsyncClient, ): - super().__init__(access_token=access_token, base_url=base_url, timeout=timeout) + super().__init__(access_token=access_token, environment=environment, timeout=timeout) self.httpx_client = AsyncHttpClient( - httpx_client=httpx_client, - base_headers=self.get_headers, - base_timeout=self.get_timeout, - base_url=self.get_base_url, + httpx_client=httpx_client, base_headers=self.get_headers, base_timeout=self.get_timeout ) diff --git a/src/webflow/environment.py b/src/webflow/environment.py index ed0e03d..07a5c81 100644 --- a/src/webflow/environment.py +++ b/src/webflow/environment.py @@ -1,7 +1,19 @@ # This file was auto-generated by Fern from our API Definition. -import enum +from __future__ import annotations -class WebflowEnvironment(enum.Enum): - DEFAULT = "https://api.webflow.com/v2" +class WebflowEnvironment: + DATA_API: WebflowEnvironment + + def __init__(self, *, base: str, data_api: str, content_delivery_api: str): + self.base = base + self.data_api = data_api + self.content_delivery_api = content_delivery_api + + +WebflowEnvironment.DATA_API = WebflowEnvironment( + base="https://api.webflow.com/v2", + data_api="https://api.webflow.com/v2", + content_delivery_api="https://api-cdn.webflow.com/v2", +) diff --git a/src/webflow/resources/__init__.py b/src/webflow/resources/__init__.py index 9122eee..eb58716 100644 --- a/src/webflow/resources/__init__.py +++ b/src/webflow/resources/__init__.py @@ -1,7 +1,6 @@ # This file was auto-generated by Fern from our API Definition. from . import ( - access_groups, assets, collections, components, @@ -14,39 +13,38 @@ scripts, sites, token, - users, webhooks, + workspaces, ) -from .access_groups import AccessGroupsListRequestSort from .components import ( ComponentDomWriteNodesItem, ComponentPropertiesWritePropertiesItem, ComponentsUpdateContentResponse, ComponentsUpdatePropertiesResponse, ) -from .inventory import InventoryUpdateRequestInventoryType +from .inventory import EcommInventoryChangedPayload, InventoryUpdateRequestInventoryType from .orders import OrdersListRequestStatus, OrdersRefundRequestReason -from .pages import PageDomWriteNodesItem, UpdateStaticContentResponse -from .products import ProductsCreateSkuResponse +from .pages import PageDomWriteNodesItem, PageMetadataWriteOpenGraph, PageMetadataWriteSeo, UpdateStaticContentResponse +from .products import ProductSkuCreateProduct, ProductSkuCreateSku, ProductsCreateSkuResponse from .sites import SitesPublishResponse -from .users import UsersListRequestSort, UsersUpdateRequestData __all__ = [ - "AccessGroupsListRequestSort", "ComponentDomWriteNodesItem", "ComponentPropertiesWritePropertiesItem", "ComponentsUpdateContentResponse", "ComponentsUpdatePropertiesResponse", + "EcommInventoryChangedPayload", "InventoryUpdateRequestInventoryType", "OrdersListRequestStatus", "OrdersRefundRequestReason", "PageDomWriteNodesItem", + "PageMetadataWriteOpenGraph", + "PageMetadataWriteSeo", + "ProductSkuCreateProduct", + "ProductSkuCreateSku", "ProductsCreateSkuResponse", "SitesPublishResponse", "UpdateStaticContentResponse", - "UsersListRequestSort", - "UsersUpdateRequestData", - "access_groups", "assets", "collections", "components", @@ -59,6 +57,6 @@ "scripts", "sites", "token", - "users", "webhooks", + "workspaces", ] diff --git a/src/webflow/resources/access_groups/__init__.py b/src/webflow/resources/access_groups/__init__.py deleted file mode 100644 index b46e2ae..0000000 --- a/src/webflow/resources/access_groups/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from .types import AccessGroupsListRequestSort - -__all__ = ["AccessGroupsListRequestSort"] diff --git a/src/webflow/resources/access_groups/types/__init__.py b/src/webflow/resources/access_groups/types/__init__.py deleted file mode 100644 index e721e22..0000000 --- a/src/webflow/resources/access_groups/types/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from .access_groups_list_request_sort import AccessGroupsListRequestSort - -__all__ = ["AccessGroupsListRequestSort"] diff --git a/src/webflow/resources/access_groups/types/access_groups_list_request_sort.py b/src/webflow/resources/access_groups/types/access_groups_list_request_sort.py deleted file mode 100644 index 074583a..0000000 --- a/src/webflow/resources/access_groups/types/access_groups_list_request_sort.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -AccessGroupsListRequestSort = typing.Union[typing.Literal["CreatedOn", "-CreatedOn"], typing.Any] diff --git a/src/webflow/resources/assets/client.py b/src/webflow/resources/assets/client.py index 61e141a..d2723f9 100644 --- a/src/webflow/resources/assets/client.py +++ b/src/webflow/resources/assets/client.py @@ -28,9 +28,16 @@ class AssetsClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper - def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Assets: + def list( + self, + site_id: str, + *, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Assets: """ - List assets for a given site + List of assets uploaded to a site Required scope | `assets:read` @@ -39,6 +46,12 @@ def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] site_id : str Unique identifier for a Site + offset : typing.Optional[int] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[int] + Maximum number of records to be returned (max limit: 100) + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -56,11 +69,18 @@ def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] ) client.assets.list( site_id="580e63e98c9a982ac9b8b741", + offset=1, + limit=1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/assets", + base_url=self._client_wrapper.get_environment().base, method="GET", + params={ + "offset": offset, + "limit": limit, + }, request_options=request_options, ) try: @@ -137,15 +157,18 @@ def create( request_options: typing.Optional[RequestOptions] = None, ) -> AssetUpload: """ - Create a new asset entry. + The first step in uploading an asset to a site. This endpoint generates a response with the following information: `uploadUrl` and `uploadDetails`. - You can use these two properties to [upload the file to Amazon s3 by making a POST](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) - request to the `uploadUrl` with the `uploadDetails` object as your header information in the request. - Required scope | `assets:write` + Use these properties in the header of a [POST request to Amazson s3](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) to complete the upload. + + + To learn more about how to upload assets to Webflow, see our [assets guide](/data/docs/working-with-assets). + + Required scope | `assets:write` Parameters ---------- @@ -184,6 +207,7 @@ def create( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/assets", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "fileName": file_name, @@ -262,7 +286,7 @@ def create( def get(self, asset_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Asset: """ - Get an Asset + Get details about an asset Required scope | `assets:read` @@ -292,6 +316,7 @@ def get(self, asset_id: str, *, request_options: typing.Optional[RequestOptions] """ _response = self._client_wrapper.httpx_client.request( f"assets/{jsonable_encoder(asset_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -390,6 +415,7 @@ def delete(self, asset_id: str, *, request_options: typing.Optional[RequestOptio """ _response = self._client_wrapper.httpx_client.request( f"assets/{jsonable_encoder(asset_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -460,7 +486,7 @@ def update( request_options: typing.Optional[RequestOptions] = None, ) -> Asset: """ - Update an Asset + Update details of an Asset. Required scope | `assets:write` @@ -496,6 +522,7 @@ def update( """ _response = self._client_wrapper.httpx_client.request( f"assets/{jsonable_encoder(asset_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "localeId": locale_id, @@ -603,6 +630,7 @@ def list_folders(self, site_id: str, *, request_options: typing.Optional[Request """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/asset_folders", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -716,6 +744,7 @@ def create_folder( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/asset_folders", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "displayName": display_name, @@ -825,6 +854,7 @@ def get_folder( """ _response = self._client_wrapper.httpx_client.request( f"asset_folders/{jsonable_encoder(asset_folder_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -897,9 +927,16 @@ class AsyncAssetsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper - async def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Assets: + async def list( + self, + site_id: str, + *, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Assets: """ - List assets for a given site + List of assets uploaded to a site Required scope | `assets:read` @@ -908,6 +945,12 @@ async def list(self, site_id: str, *, request_options: typing.Optional[RequestOp site_id : str Unique identifier for a Site + offset : typing.Optional[int] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[int] + Maximum number of records to be returned (max limit: 100) + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -930,6 +973,8 @@ async def list(self, site_id: str, *, request_options: typing.Optional[RequestOp async def main() -> None: await client.assets.list( site_id="580e63e98c9a982ac9b8b741", + offset=1, + limit=1, ) @@ -937,7 +982,12 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/assets", + base_url=self._client_wrapper.get_environment().base, method="GET", + params={ + "offset": offset, + "limit": limit, + }, request_options=request_options, ) try: @@ -1014,15 +1064,18 @@ async def create( request_options: typing.Optional[RequestOptions] = None, ) -> AssetUpload: """ - Create a new asset entry. + The first step in uploading an asset to a site. This endpoint generates a response with the following information: `uploadUrl` and `uploadDetails`. - You can use these two properties to [upload the file to Amazon s3 by making a POST](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) - request to the `uploadUrl` with the `uploadDetails` object as your header information in the request. - Required scope | `assets:write` + Use these properties in the header of a [POST request to Amazson s3](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) to complete the upload. + + + To learn more about how to upload assets to Webflow, see our [assets guide](/data/docs/working-with-assets). + + Required scope | `assets:write` Parameters ---------- @@ -1069,6 +1122,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/assets", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "fileName": file_name, @@ -1147,7 +1201,7 @@ async def main() -> None: async def get(self, asset_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Asset: """ - Get an Asset + Get details about an asset Required scope | `assets:read` @@ -1185,6 +1239,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"assets/{jsonable_encoder(asset_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -1291,6 +1346,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"assets/{jsonable_encoder(asset_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -1361,7 +1417,7 @@ async def update( request_options: typing.Optional[RequestOptions] = None, ) -> Asset: """ - Update an Asset + Update details of an Asset. Required scope | `assets:write` @@ -1405,6 +1461,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"assets/{jsonable_encoder(asset_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "localeId": locale_id, @@ -1522,6 +1579,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/asset_folders", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -1643,6 +1701,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/asset_folders", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "displayName": display_name, @@ -1760,6 +1819,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"asset_folders/{jsonable_encoder(asset_folder_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) diff --git a/src/webflow/resources/collections/__init__.py b/src/webflow/resources/collections/__init__.py index cb6aaf8..3796806 100644 --- a/src/webflow/resources/collections/__init__.py +++ b/src/webflow/resources/collections/__init__.py @@ -3,16 +3,20 @@ from .resources import ( CreateBulkCollectionItemRequestBodyFieldData, CreateBulkCollectionItemRequestBodyFieldDataItem, - FieldCreateType, - ItemsCreateItemLiveRequest, - ItemsCreateItemRequest, + ItemIDs, + ItemIDsWithLocales, + ItemsCreateItemLiveRequestBody, + ItemsCreateItemRequestBody, ItemsDeleteItemsLiveRequestItemsItem, ItemsDeleteItemsRequestItemsItem, ItemsListItemsLiveRequestSortBy, ItemsListItemsLiveRequestSortOrder, ItemsListItemsRequestSortBy, ItemsListItemsRequestSortOrder, + ItemsPublishItemRequest, + ItemsPublishItemRequestItemsItemsItem, ItemsPublishItemResponse, + ItemsUpdateItemsResponse, MultipleItems, MultipleLiveItems, SingleCmsItem, @@ -23,16 +27,20 @@ __all__ = [ "CreateBulkCollectionItemRequestBodyFieldData", "CreateBulkCollectionItemRequestBodyFieldDataItem", - "FieldCreateType", - "ItemsCreateItemLiveRequest", - "ItemsCreateItemRequest", + "ItemIDs", + "ItemIDsWithLocales", + "ItemsCreateItemLiveRequestBody", + "ItemsCreateItemRequestBody", "ItemsDeleteItemsLiveRequestItemsItem", "ItemsDeleteItemsRequestItemsItem", "ItemsListItemsLiveRequestSortBy", "ItemsListItemsLiveRequestSortOrder", "ItemsListItemsRequestSortBy", "ItemsListItemsRequestSortOrder", + "ItemsPublishItemRequest", + "ItemsPublishItemRequestItemsItemsItem", "ItemsPublishItemResponse", + "ItemsUpdateItemsResponse", "MultipleItems", "MultipleLiveItems", "SingleCmsItem", diff --git a/src/webflow/resources/collections/client.py b/src/webflow/resources/collections/client.py index 1e44aae..61495ae 100644 --- a/src/webflow/resources/collections/client.py +++ b/src/webflow/resources/collections/client.py @@ -16,7 +16,10 @@ from ...errors.internal_server_error import InternalServerError from json.decoder import JSONDecodeError from ...core.api_error import ApiError +from ...types.field_create import FieldCreate from ...types.collection import Collection +from ...core.serialization import convert_and_respect_annotation_metadata +from ...errors.conflict_error import ConflictError from ...core.client_wrapper import AsyncClientWrapper from .resources.fields.client import AsyncFieldsClient from .resources.items.client import AsyncItemsClient @@ -63,6 +66,7 @@ def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/collections", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -137,10 +141,13 @@ def create( display_name: str, singular_name: str, slug: typing.Optional[str] = OMIT, + fields: typing.Optional[typing.Sequence[FieldCreate]] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Collection: """ - Create a Collection for a site. + Create a Collection for a site with collection fields. + + Each collection includes the required _name_ and _slug_ fields, which are generated automatically. You can update the `displayName` of these fields, but the slug for them cannot be changed. Fields slugs are automatically converted to lowercase. Spaces in slugs are replaced with hyphens. Required scope | `cms:write` @@ -158,6 +165,9 @@ def create( slug : typing.Optional[str] Part of a URL that identifier + fields : typing.Optional[typing.Sequence[FieldCreate]] + An array of custom fields to add to the collection + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -168,7 +178,7 @@ def create( Examples -------- - from webflow import Webflow + from webflow import ReferenceField, ReferenceFieldMetadata, StaticField, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", @@ -178,15 +188,42 @@ def create( display_name="Blog Posts", singular_name="Blog Post", slug="posts", + fields=[ + StaticField( + is_required=True, + type="PlainText", + display_name="Title", + help_text="The title of the blog post", + ), + StaticField( + is_required=True, + type="RichText", + display_name="Content", + help_text="The content of the blog post", + ), + ReferenceField( + is_required=True, + type="Reference", + display_name="Author", + help_text="The author of the blog post", + metadata=ReferenceFieldMetadata( + collection_id="23cc2d952d4e4631ffd4345d2743db4e", + ), + ), + ], ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/collections", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "displayName": display_name, "singularName": singular_name, "slug": slug, + "fields": convert_and_respect_annotation_metadata( + object_=fields, annotation=typing.Sequence[FieldCreate], direction="write" + ), }, headers={ "content-type": "application/json", @@ -233,6 +270,16 @@ def create( ), ) ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) if _response.status_code == 429: raise TooManyRequestsError( typing.cast( @@ -290,6 +337,7 @@ def get(self, collection_id: str, *, request_options: typing.Optional[RequestOpt """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -388,6 +436,7 @@ def delete(self, collection_id: str, *, request_options: typing.Optional[Request """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -496,6 +545,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/collections", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -570,10 +620,13 @@ async def create( display_name: str, singular_name: str, slug: typing.Optional[str] = OMIT, + fields: typing.Optional[typing.Sequence[FieldCreate]] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Collection: """ - Create a Collection for a site. + Create a Collection for a site with collection fields. + + Each collection includes the required _name_ and _slug_ fields, which are generated automatically. You can update the `displayName` of these fields, but the slug for them cannot be changed. Fields slugs are automatically converted to lowercase. Spaces in slugs are replaced with hyphens. Required scope | `cms:write` @@ -591,6 +644,9 @@ async def create( slug : typing.Optional[str] Part of a URL that identifier + fields : typing.Optional[typing.Sequence[FieldCreate]] + An array of custom fields to add to the collection + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -603,7 +659,12 @@ async def create( -------- import asyncio - from webflow import AsyncWebflow + from webflow import ( + AsyncWebflow, + ReferenceField, + ReferenceFieldMetadata, + StaticField, + ) client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -616,6 +677,29 @@ async def main() -> None: display_name="Blog Posts", singular_name="Blog Post", slug="posts", + fields=[ + StaticField( + is_required=True, + type="PlainText", + display_name="Title", + help_text="The title of the blog post", + ), + StaticField( + is_required=True, + type="RichText", + display_name="Content", + help_text="The content of the blog post", + ), + ReferenceField( + is_required=True, + type="Reference", + display_name="Author", + help_text="The author of the blog post", + metadata=ReferenceFieldMetadata( + collection_id="23cc2d952d4e4631ffd4345d2743db4e", + ), + ), + ], ) @@ -623,11 +707,15 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/collections", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "displayName": display_name, "singularName": singular_name, "slug": slug, + "fields": convert_and_respect_annotation_metadata( + object_=fields, annotation=typing.Sequence[FieldCreate], direction="write" + ), }, headers={ "content-type": "application/json", @@ -674,6 +762,16 @@ async def main() -> None: ), ) ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) if _response.status_code == 429: raise TooManyRequestsError( typing.cast( @@ -739,6 +837,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -845,6 +944,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) diff --git a/src/webflow/resources/collections/resources/__init__.py b/src/webflow/resources/collections/resources/__init__.py index f9325ee..4ad4d58 100644 --- a/src/webflow/resources/collections/resources/__init__.py +++ b/src/webflow/resources/collections/resources/__init__.py @@ -1,19 +1,23 @@ # This file was auto-generated by Fern from our API Definition. from . import fields, items -from .fields import FieldCreateType from .items import ( CreateBulkCollectionItemRequestBodyFieldData, CreateBulkCollectionItemRequestBodyFieldDataItem, - ItemsCreateItemLiveRequest, - ItemsCreateItemRequest, + ItemIDs, + ItemIDsWithLocales, + ItemsCreateItemLiveRequestBody, + ItemsCreateItemRequestBody, ItemsDeleteItemsLiveRequestItemsItem, ItemsDeleteItemsRequestItemsItem, ItemsListItemsLiveRequestSortBy, ItemsListItemsLiveRequestSortOrder, ItemsListItemsRequestSortBy, ItemsListItemsRequestSortOrder, + ItemsPublishItemRequest, + ItemsPublishItemRequestItemsItemsItem, ItemsPublishItemResponse, + ItemsUpdateItemsResponse, MultipleItems, MultipleLiveItems, SingleCmsItem, @@ -22,16 +26,20 @@ __all__ = [ "CreateBulkCollectionItemRequestBodyFieldData", "CreateBulkCollectionItemRequestBodyFieldDataItem", - "FieldCreateType", - "ItemsCreateItemLiveRequest", - "ItemsCreateItemRequest", + "ItemIDs", + "ItemIDsWithLocales", + "ItemsCreateItemLiveRequestBody", + "ItemsCreateItemRequestBody", "ItemsDeleteItemsLiveRequestItemsItem", "ItemsDeleteItemsRequestItemsItem", "ItemsListItemsLiveRequestSortBy", "ItemsListItemsLiveRequestSortOrder", "ItemsListItemsRequestSortBy", "ItemsListItemsRequestSortOrder", + "ItemsPublishItemRequest", + "ItemsPublishItemRequestItemsItemsItem", "ItemsPublishItemResponse", + "ItemsUpdateItemsResponse", "MultipleItems", "MultipleLiveItems", "SingleCmsItem", diff --git a/src/webflow/resources/collections/resources/fields/__init__.py b/src/webflow/resources/collections/resources/fields/__init__.py index 5a5b167..f3ea265 100644 --- a/src/webflow/resources/collections/resources/fields/__init__.py +++ b/src/webflow/resources/collections/resources/fields/__init__.py @@ -1,5 +1,2 @@ # This file was auto-generated by Fern from our API Definition. -from .types import FieldCreateType - -__all__ = ["FieldCreateType"] diff --git a/src/webflow/resources/collections/resources/fields/client.py b/src/webflow/resources/collections/resources/fields/client.py index 40b66cf..c2b7ebc 100644 --- a/src/webflow/resources/collections/resources/fields/client.py +++ b/src/webflow/resources/collections/resources/fields/client.py @@ -2,19 +2,21 @@ import typing from .....core.client_wrapper import SyncClientWrapper -from .types.field_create_type import FieldCreateType +from .....types.field_create import FieldCreate from .....core.request_options import RequestOptions -from .....types.field import Field from .....core.jsonable_encoder import jsonable_encoder +from .....core.serialization import convert_and_respect_annotation_metadata from .....core.pydantic_utilities import parse_obj_as from .....errors.bad_request_error import BadRequestError from .....errors.unauthorized_error import UnauthorizedError from .....types.error import Error from .....errors.not_found_error import NotFoundError +from .....errors.conflict_error import ConflictError from .....errors.too_many_requests_error import TooManyRequestsError from .....errors.internal_server_error import InternalServerError from json.decoder import JSONDecodeError from .....core.api_error import ApiError +from .....types.field import Field from .....core.client_wrapper import AsyncClientWrapper # this is used as the default value for optional parameters @@ -26,24 +28,14 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper def create( - self, - collection_id: str, - *, - type: FieldCreateType, - display_name: str, - is_required: typing.Optional[bool] = OMIT, - help_text: typing.Optional[str] = OMIT, - request_options: typing.Optional[RequestOptions] = None, - ) -> Field: + self, collection_id: str, *, request: FieldCreate, request_options: typing.Optional[RequestOptions] = None + ) -> FieldCreate: """ Create a custom field in a collection. - Slugs must be all lowercase letters without spaces. - If you pass a string with uppercase letters and/or spaces to the "Slug" property, Webflow will - convert the slug to lowercase and replace spaces with "-." + Field validation is currently not available through the API. - Only some field types can be created through the API. - This endpoint does not currently support bulk creation. + Bulk creation of fields is not supported with this endpoint. To add multiple fields at once, include them when you [create the collection.](/data/v2.0.0/reference/cms/collections/create) Required scope | `cms:write` @@ -52,62 +44,49 @@ def create( collection_id : str Unique identifier for a Collection - type : FieldCreateType - Choose these appropriate field type for your collection data - - display_name : str - The name of a field - - is_required : typing.Optional[bool] - define whether a field is required in a collection - - help_text : typing.Optional[str] - Additional text to help anyone filling out this field + request : FieldCreate request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - Field + FieldCreate Request was successful Examples -------- - from webflow import Webflow + from webflow import StaticField, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.collections.fields.create( collection_id="580e63fc8c9a982ac9b8b745", - is_required=False, - type="RichText", - display_name="Post Body", - help_text="Add the body of your post here", + request=StaticField( + id="562ac0395358780a1f5e6fbc", + is_editable=True, + is_required=False, + type="RichText", + display_name="Post Body", + help_text="Add the body of your post here", + ), ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/fields", + base_url=self._client_wrapper.get_environment().base, method="POST", - json={ - "isRequired": is_required, - "type": type, - "displayName": display_name, - "helpText": help_text, - }, - headers={ - "content-type": "application/json", - }, + json=convert_and_respect_annotation_metadata(object_=request, annotation=FieldCreate, direction="write"), request_options=request_options, omit=OMIT, ) try: if 200 <= _response.status_code < 300: return typing.cast( - Field, + FieldCreate, parse_obj_as( - type_=Field, # type: ignore + type_=FieldCreate, # type: ignore object_=_response.json(), ), ) @@ -141,6 +120,16 @@ def create( ), ) ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) if _response.status_code == 429: raise TooManyRequestsError( typing.cast( @@ -203,6 +192,7 @@ def delete( """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/fields/{jsonable_encoder(field_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -321,6 +311,7 @@ def update( """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/fields/{jsonable_encoder(field_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "isRequired": is_required, @@ -403,24 +394,14 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper async def create( - self, - collection_id: str, - *, - type: FieldCreateType, - display_name: str, - is_required: typing.Optional[bool] = OMIT, - help_text: typing.Optional[str] = OMIT, - request_options: typing.Optional[RequestOptions] = None, - ) -> Field: + self, collection_id: str, *, request: FieldCreate, request_options: typing.Optional[RequestOptions] = None + ) -> FieldCreate: """ Create a custom field in a collection. - Slugs must be all lowercase letters without spaces. - If you pass a string with uppercase letters and/or spaces to the "Slug" property, Webflow will - convert the slug to lowercase and replace spaces with "-." + Field validation is currently not available through the API. - Only some field types can be created through the API. - This endpoint does not currently support bulk creation. + Bulk creation of fields is not supported with this endpoint. To add multiple fields at once, include them when you [create the collection.](/data/v2.0.0/reference/cms/collections/create) Required scope | `cms:write` @@ -429,31 +410,21 @@ async def create( collection_id : str Unique identifier for a Collection - type : FieldCreateType - Choose these appropriate field type for your collection data - - display_name : str - The name of a field - - is_required : typing.Optional[bool] - define whether a field is required in a collection - - help_text : typing.Optional[str] - Additional text to help anyone filling out this field + request : FieldCreate request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - Field + FieldCreate Request was successful Examples -------- import asyncio - from webflow import AsyncWebflow + from webflow import AsyncWebflow, StaticField client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -463,10 +434,14 @@ async def create( async def main() -> None: await client.collections.fields.create( collection_id="580e63fc8c9a982ac9b8b745", - is_required=False, - type="RichText", - display_name="Post Body", - help_text="Add the body of your post here", + request=StaticField( + id="562ac0395358780a1f5e6fbc", + is_editable=True, + is_required=False, + type="RichText", + display_name="Post Body", + help_text="Add the body of your post here", + ), ) @@ -474,25 +449,18 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/fields", + base_url=self._client_wrapper.get_environment().base, method="POST", - json={ - "isRequired": is_required, - "type": type, - "displayName": display_name, - "helpText": help_text, - }, - headers={ - "content-type": "application/json", - }, + json=convert_and_respect_annotation_metadata(object_=request, annotation=FieldCreate, direction="write"), request_options=request_options, omit=OMIT, ) try: if 200 <= _response.status_code < 300: return typing.cast( - Field, + FieldCreate, parse_obj_as( - type_=Field, # type: ignore + type_=FieldCreate, # type: ignore object_=_response.json(), ), ) @@ -526,6 +494,16 @@ async def main() -> None: ), ) ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) if _response.status_code == 429: raise TooManyRequestsError( typing.cast( @@ -596,6 +574,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/fields/{jsonable_encoder(field_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -722,6 +701,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/fields/{jsonable_encoder(field_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "isRequired": is_required, diff --git a/src/webflow/resources/collections/resources/fields/types/__init__.py b/src/webflow/resources/collections/resources/fields/types/__init__.py deleted file mode 100644 index c17230e..0000000 --- a/src/webflow/resources/collections/resources/fields/types/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from .field_create_type import FieldCreateType - -__all__ = ["FieldCreateType"] diff --git a/src/webflow/resources/collections/resources/items/__init__.py b/src/webflow/resources/collections/resources/items/__init__.py index fbccd1b..7dce40c 100644 --- a/src/webflow/resources/collections/resources/items/__init__.py +++ b/src/webflow/resources/collections/resources/items/__init__.py @@ -3,15 +3,20 @@ from .types import ( CreateBulkCollectionItemRequestBodyFieldData, CreateBulkCollectionItemRequestBodyFieldDataItem, - ItemsCreateItemLiveRequest, - ItemsCreateItemRequest, + ItemIDs, + ItemIDsWithLocales, + ItemsCreateItemLiveRequestBody, + ItemsCreateItemRequestBody, ItemsDeleteItemsLiveRequestItemsItem, ItemsDeleteItemsRequestItemsItem, ItemsListItemsLiveRequestSortBy, ItemsListItemsLiveRequestSortOrder, ItemsListItemsRequestSortBy, ItemsListItemsRequestSortOrder, + ItemsPublishItemRequest, + ItemsPublishItemRequestItemsItemsItem, ItemsPublishItemResponse, + ItemsUpdateItemsResponse, MultipleItems, MultipleLiveItems, SingleCmsItem, @@ -20,15 +25,20 @@ __all__ = [ "CreateBulkCollectionItemRequestBodyFieldData", "CreateBulkCollectionItemRequestBodyFieldDataItem", - "ItemsCreateItemLiveRequest", - "ItemsCreateItemRequest", + "ItemIDs", + "ItemIDsWithLocales", + "ItemsCreateItemLiveRequestBody", + "ItemsCreateItemRequestBody", "ItemsDeleteItemsLiveRequestItemsItem", "ItemsDeleteItemsRequestItemsItem", "ItemsListItemsLiveRequestSortBy", "ItemsListItemsLiveRequestSortOrder", "ItemsListItemsRequestSortBy", "ItemsListItemsRequestSortOrder", + "ItemsPublishItemRequest", + "ItemsPublishItemRequestItemsItemsItem", "ItemsPublishItemResponse", + "ItemsUpdateItemsResponse", "MultipleItems", "MultipleLiveItems", "SingleCmsItem", diff --git a/src/webflow/resources/collections/resources/items/client.py b/src/webflow/resources/collections/resources/items/client.py index 47f8f90..0e04307 100644 --- a/src/webflow/resources/collections/resources/items/client.py +++ b/src/webflow/resources/collections/resources/items/client.py @@ -2,11 +2,13 @@ import typing from .....core.client_wrapper import SyncClientWrapper +from .....types.items_list_items_request_last_published import ItemsListItemsRequestLastPublished from .types.items_list_items_request_sort_by import ItemsListItemsRequestSortBy from .types.items_list_items_request_sort_order import ItemsListItemsRequestSortOrder from .....core.request_options import RequestOptions from .....types.collection_item_list import CollectionItemList from .....core.jsonable_encoder import jsonable_encoder +from .....core.serialization import convert_and_respect_annotation_metadata from .....core.pydantic_utilities import parse_obj_as from .....errors.bad_request_error import BadRequestError from .....errors.unauthorized_error import UnauthorizedError @@ -16,20 +18,22 @@ from .....errors.internal_server_error import InternalServerError from json.decoder import JSONDecodeError from .....core.api_error import ApiError -from .types.items_create_item_request import ItemsCreateItemRequest +from .types.items_create_item_request_body import ItemsCreateItemRequestBody from .....types.collection_item import CollectionItem -from .....core.serialization import convert_and_respect_annotation_metadata from .types.items_delete_items_request_items_item import ItemsDeleteItemsRequestItemsItem from .....errors.conflict_error import ConflictError from .....types.collection_item_with_id_input import CollectionItemWithIdInput +from .types.items_update_items_response import ItemsUpdateItemsResponse +from .....types.items_list_items_live_request_last_published import ItemsListItemsLiveRequestLastPublished from .types.items_list_items_live_request_sort_by import ItemsListItemsLiveRequestSortBy from .types.items_list_items_live_request_sort_order import ItemsListItemsLiveRequestSortOrder -from .types.items_create_item_live_request import ItemsCreateItemLiveRequest +from .types.items_create_item_live_request_body import ItemsCreateItemLiveRequestBody from .types.items_delete_items_live_request_items_item import ItemsDeleteItemsLiveRequestItemsItem from .....types.collection_item_list_no_pagination import CollectionItemListNoPagination from .types.create_bulk_collection_item_request_body_field_data import CreateBulkCollectionItemRequestBodyFieldData from .....types.bulk_collection_item import BulkCollectionItem from .....types.collection_item_patch_single_field_data import CollectionItemPatchSingleFieldData +from .types.items_publish_item_request import ItemsPublishItemRequest from .types.items_publish_item_response import ItemsPublishItemResponse from .....core.client_wrapper import AsyncClientWrapper @@ -46,10 +50,11 @@ def list_items( collection_id: str, *, cms_locale_id: typing.Optional[str] = None, - offset: typing.Optional[float] = None, - limit: typing.Optional[float] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, name: typing.Optional[str] = None, slug: typing.Optional[str] = None, + last_published: typing.Optional[ItemsListItemsRequestLastPublished] = None, sort_by: typing.Optional[ItemsListItemsRequestSortBy] = None, sort_order: typing.Optional[ItemsListItemsRequestSortOrder] = None, request_options: typing.Optional[RequestOptions] = None, @@ -67,17 +72,20 @@ def list_items( cms_locale_id : typing.Optional[str] Unique identifier for a CMS Locale. This UID is different from the Site locale identifier and is listed as `cmsLocaleId` in the Sites response. To query multiple locales, input a comma separated string. - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records - limit : typing.Optional[float] + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) name : typing.Optional[str] - The name of the item(s) + Filter by the exact name of the item(s) slug : typing.Optional[str] - The slug of the item + Filter by the exact slug of the item + + last_published : typing.Optional[ItemsListItemsRequestLastPublished] + Filter by the last published date of the item(s) sort_by : typing.Optional[ItemsListItemsRequestSortBy] Sort results by the provided value @@ -102,10 +110,18 @@ def list_items( ) client.collections.items.list_items( collection_id="580e63fc8c9a982ac9b8b745", + cms_locale_id="cmsLocaleId", + offset=1, + limit=1, + name="name", + slug="slug", + sort_by="lastPublished", + sort_order="asc", ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "cmsLocaleId": cms_locale_id, @@ -113,6 +129,9 @@ def list_items( "limit": limit, "name": name, "slug": slug, + "lastPublished": convert_and_respect_annotation_metadata( + object_=last_published, annotation=ItemsListItemsRequestLastPublished, direction="write" + ), "sortBy": sort_by, "sortOrder": sort_order, }, @@ -186,14 +205,15 @@ def create_item( self, collection_id: str, *, - request: ItemsCreateItemRequest, + request: ItemsCreateItemRequestBody, + skip_invalid_files: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> CollectionItem: """ Create Item(s) in a Collection. - To create items across multiple locales, please use [this endpoint.](/v2.0.0/data/reference/cms/collection-items/staged-items/create-items) + To create items across multiple locales, please use [this endpoint.](/data/reference/cms/collection-items/staged-items/create-items) Required scope | `CMS:write` @@ -202,7 +222,10 @@ def create_item( collection_id : str Unique identifier for a Collection - request : ItemsCreateItemRequest + request : ItemsCreateItemRequestBody + + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -225,21 +248,26 @@ def create_item( ) client.collections.items.create_item( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, request=CollectionItemPostSingle( is_archived=False, is_draft=False, field_data=CollectionItemPostSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", ), ), ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items", + base_url=self._client_wrapper.get_environment().base, method="POST", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json=convert_and_respect_annotation_metadata( - object_=request, annotation=ItemsCreateItemRequest, direction="write" + object_=request, annotation=ItemsCreateItemRequestBody, direction="write" ), request_options=request_options, omit=OMIT, @@ -312,13 +340,13 @@ def delete_items( self, collection_id: str, *, - items: typing.Optional[typing.Sequence[ItemsDeleteItemsRequestItemsItem]] = OMIT, + items: typing.Sequence[ItemsDeleteItemsRequestItemsItem], request_options: typing.Optional[RequestOptions] = None, ) -> None: """ Delete Items from a Collection. - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be deleted only in the primary locale. + Items will only be deleted in the primary locale unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -327,7 +355,7 @@ def delete_items( collection_id : str Unique identifier for a Collection - items : typing.Optional[typing.Sequence[ItemsDeleteItemsRequestItemsItem]] + items : typing.Sequence[ItemsDeleteItemsRequestItemsItem] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -339,16 +367,25 @@ def delete_items( Examples -------- from webflow import Webflow + from webflow.resources.collections.resources.items import ( + ItemsDeleteItemsRequestItemsItem, + ) client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.collections.items.delete_items( collection_id="580e63fc8c9a982ac9b8b745", + items=[ + ItemsDeleteItemsRequestItemsItem( + id="580e64008c9a982ac9b8b754", + ) + ], ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items", + base_url=self._client_wrapper.get_environment().base, method="DELETE", json={ "items": convert_and_respect_annotation_metadata( @@ -433,13 +470,16 @@ def update_items( self, collection_id: str, *, + skip_invalid_files: typing.Optional[bool] = None, items: typing.Optional[typing.Sequence[CollectionItemWithIdInput]] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> CollectionItem: + ) -> ItemsUpdateItemsResponse: """ - Update a single item or multiple items (up to 100) in a Collection. + Update a single item or multiple items in a Collection. - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be updated only in the primary locale. + The limit for this endpoint is 100 items. + + Items will only be updated in the primary locale, unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -448,6 +488,9 @@ def update_items( collection_id : str Unique identifier for a Collection + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + items : typing.Optional[typing.Sequence[CollectionItemWithIdInput]] request_options : typing.Optional[RequestOptions] @@ -455,7 +498,7 @@ def update_items( Returns ------- - CollectionItem + ItemsUpdateItemsResponse Request was successful Examples @@ -471,6 +514,7 @@ def update_items( ) client.collections.items.update_items( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, items=[ CollectionItemWithIdInput( id="66f6ed9576ddacf3149d5ea6", @@ -509,7 +553,11 @@ def update_items( """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items", + base_url=self._client_wrapper.get_environment().base, method="PATCH", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "items": convert_and_respect_annotation_metadata( object_=items, annotation=typing.Sequence[CollectionItemWithIdInput], direction="write" @@ -524,9 +572,9 @@ def update_items( try: if 200 <= _response.status_code < 300: return typing.cast( - CollectionItem, + ItemsUpdateItemsResponse, parse_obj_as( - type_=CollectionItem, # type: ignore + type_=ItemsUpdateItemsResponse, # type: ignore object_=_response.json(), ), ) @@ -590,16 +638,21 @@ def list_items_live( collection_id: str, *, cms_locale_id: typing.Optional[str] = None, - offset: typing.Optional[float] = None, - limit: typing.Optional[float] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, name: typing.Optional[str] = None, slug: typing.Optional[str] = None, + last_published: typing.Optional[ItemsListItemsLiveRequestLastPublished] = None, sort_by: typing.Optional[ItemsListItemsLiveRequestSortBy] = None, sort_order: typing.Optional[ItemsListItemsLiveRequestSortOrder] = None, request_options: typing.Optional[RequestOptions] = None, ) -> CollectionItemList: """ - List of all live Items within a Collection. + List all published items in a collection. + + + Serving data to applications in real-time? Use the Content Delivery API at `api-cdn.webflow.com` for better performance. The CDN-backed endpoint is optimized for high-volume reads, while the Data API is designed for writes and management operations. + Required scope | `CMS:read` @@ -611,17 +664,20 @@ def list_items_live( cms_locale_id : typing.Optional[str] Unique identifier for a CMS Locale. This UID is different from the Site locale identifier and is listed as `cmsLocaleId` in the Sites response. To query multiple locales, input a comma separated string. - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records - limit : typing.Optional[float] + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) name : typing.Optional[str] - The name of the item(s) + Filter by the exact name of the item(s) slug : typing.Optional[str] - The slug of the item + Filter by the exact slug of the item + + last_published : typing.Optional[ItemsListItemsLiveRequestLastPublished] + Filter by the last published date of the item(s) sort_by : typing.Optional[ItemsListItemsLiveRequestSortBy] Sort results by the provided value @@ -646,10 +702,18 @@ def list_items_live( ) client.collections.items.list_items_live( collection_id="580e63fc8c9a982ac9b8b745", + cms_locale_id="cmsLocaleId", + offset=1, + limit=1, + name="name", + slug="slug", + sort_by="lastPublished", + sort_order="asc", ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/live", + base_url=self._client_wrapper.get_environment().data_api, method="GET", params={ "cmsLocaleId": cms_locale_id, @@ -657,6 +721,9 @@ def list_items_live( "limit": limit, "name": name, "slug": slug, + "lastPublished": convert_and_respect_annotation_metadata( + object_=last_published, annotation=ItemsListItemsLiveRequestLastPublished, direction="write" + ), "sortBy": sort_by, "sortOrder": sort_order, }, @@ -730,14 +797,15 @@ def create_item_live( self, collection_id: str, *, - request: ItemsCreateItemLiveRequest, + request: ItemsCreateItemLiveRequestBody, + skip_invalid_files: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> CollectionItem: """ - Create live Item(s) in a Collection. The Item(s) will be published to the live site. + Create item(s) in a collection that will be immediately published to the live site. - To create items across multiple locales, [please use this endpoint.](/v2.0.0/data/reference/cms/collection-items/staged-items/create-items) + To create items across multiple locales, [please use this endpoint.](/data/reference/cms/collection-items/staged-items/create-items) Required scope | `CMS:write` @@ -747,7 +815,10 @@ def create_item_live( collection_id : str Unique identifier for a Collection - request : ItemsCreateItemLiveRequest + request : ItemsCreateItemLiveRequestBody + + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -766,21 +837,26 @@ def create_item_live( ) client.collections.items.create_item_live( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, request=CollectionItem( is_archived=False, is_draft=False, field_data=CollectionItemFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", ), ), ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/live", + base_url=self._client_wrapper.get_environment().base, method="POST", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json=convert_and_respect_annotation_metadata( - object_=request, annotation=ItemsCreateItemLiveRequest, direction="write" + object_=request, annotation=ItemsCreateItemLiveRequestBody, direction="write" ), request_options=request_options, omit=OMIT, @@ -853,13 +929,13 @@ def delete_items_live( self, collection_id: str, *, - items: typing.Optional[typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem]] = OMIT, + items: typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem], request_options: typing.Optional[RequestOptions] = None, ) -> None: """ - Remove an item or multiple items (up to 100 items) from the live site. Deleting published items will unpublish the items from the live site and set them to draft. + Unpublish up to 100 items from the live site and set the `isDraft` property to `true`. - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be unpublished only in the primary locale. + Items will only be unpublished in the primary locale unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -868,7 +944,7 @@ def delete_items_live( collection_id : str Unique identifier for a Collection - items : typing.Optional[typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem]] + items : typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -880,16 +956,25 @@ def delete_items_live( Examples -------- from webflow import Webflow + from webflow.resources.collections.resources.items import ( + ItemsDeleteItemsLiveRequestItemsItem, + ) client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.collections.items.delete_items_live( collection_id="580e63fc8c9a982ac9b8b745", + items=[ + ItemsDeleteItemsLiveRequestItemsItem( + id="580e64008c9a982ac9b8b754", + ) + ], ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/live", + base_url=self._client_wrapper.get_environment().base, method="DELETE", json={ "items": convert_and_respect_annotation_metadata( @@ -964,13 +1049,14 @@ def update_items_live( self, collection_id: str, *, + skip_invalid_files: typing.Optional[bool] = None, items: typing.Optional[typing.Sequence[CollectionItemWithIdInput]] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> CollectionItemListNoPagination: """ - Update a single live item or multiple live items (up to 100) in a Collection + Update a single published item or multiple published items (up to 100) in a Collection - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be updated only in the primary locale. + Items will only be updated in the primary locale, unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -979,6 +1065,9 @@ def update_items_live( collection_id : str Unique identifier for a Collection + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + items : typing.Optional[typing.Sequence[CollectionItemWithIdInput]] request_options : typing.Optional[RequestOptions] @@ -1002,6 +1091,7 @@ def update_items_live( ) client.collections.items.update_items_live( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, items=[ CollectionItemWithIdInput( id="66f6ed9576ddacf3149d5ea6", @@ -1040,7 +1130,11 @@ def update_items_live( """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/live", + base_url=self._client_wrapper.get_environment().base, method="PATCH", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "items": convert_and_respect_annotation_metadata( object_=items, annotation=typing.Sequence[CollectionItemWithIdInput], direction="write" @@ -1091,6 +1185,16 @@ def update_items_live( ), ) ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) if _response.status_code == 429: raise TooManyRequestsError( typing.cast( @@ -1121,6 +1225,7 @@ def create_items( collection_id: str, *, field_data: CreateBulkCollectionItemRequestBodyFieldData, + skip_invalid_files: typing.Optional[bool] = None, cms_locale_ids: typing.Optional[typing.Sequence[str]] = OMIT, is_archived: typing.Optional[bool] = OMIT, is_draft: typing.Optional[bool] = OMIT, @@ -1129,9 +1234,10 @@ def create_items( """ Create an item or multiple items in a CMS Collection across multiple corresponding locales. - **Notes:** + - This endpoint can create up to 100 items in a request. - - If the `cmsLocaleIds` parameter is undefined or empty and localization is enabled, items will only be created in the primary locale. + - If the `cmsLocaleIds` parameter is not included in the request, an item will only be created in the primary locale. + Required scope | `CMS:write` @@ -1142,6 +1248,9 @@ def create_items( field_data : CreateBulkCollectionItemRequestBodyFieldData + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + cms_locale_ids : typing.Optional[typing.Sequence[str]] Array of identifiers for the locales where the item will be created @@ -1169,6 +1278,7 @@ def create_items( ) client.collections.items.create_items( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, cms_locale_ids=[ "66f6e966c9e1dc700a857ca3", "66f6e966c9e1dc700a857ca4", @@ -1184,7 +1294,11 @@ def create_items( """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/bulk", + base_url=self._client_wrapper.get_environment().base, method="POST", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "cmsLocaleIds": cms_locale_ids, "isArchived": is_archived, @@ -1305,10 +1419,12 @@ def get_item( client.collections.items.get_item( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "cmsLocaleId": cms_locale_id, @@ -1388,7 +1504,7 @@ def delete_item( request_options: typing.Optional[RequestOptions] = None, ) -> None: """ - Delete an Item from a Collection. This endpoint does not currently support bulk deletion. + Delete an item from a collection. Required scope | `CMS:write` @@ -1420,10 +1536,12 @@ def delete_item( client.collections.items.delete_item( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", params={ "cmsLocaleId": cms_locale_id, @@ -1493,6 +1611,7 @@ def update_item( collection_id: str, item_id: str, *, + skip_invalid_files: typing.Optional[bool] = None, id: typing.Optional[str] = OMIT, cms_locale_id: typing.Optional[str] = OMIT, last_published: typing.Optional[str] = OMIT, @@ -1516,6 +1635,9 @@ def update_item( item_id : str Unique identifier for an Item + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + id : typing.Optional[str] Unique identifier for the Item @@ -1557,17 +1679,22 @@ def update_item( client.collections.items.update_item( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + skip_invalid_files=True, is_archived=False, is_draft=False, field_data=CollectionItemPatchSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", ), ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "id": id, "cmsLocaleId": cms_locale_id, @@ -1658,6 +1785,10 @@ def get_item_live( """ Get details of a selected Collection live Item. + + Serving data to applications in real-time? Use the Content Delivery API at `api-cdn.webflow.com` for better performance. The CDN-backed endpoint is optimized for high-volume reads, while the Data API is designed for writes and management operations. + + Required scope | `CMS:read` Parameters @@ -1689,10 +1820,12 @@ def get_item_live( client.collections.items.get_item_live( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/live", + base_url=self._client_wrapper.get_environment().data_api, method="GET", params={ "cmsLocaleId": cms_locale_id, @@ -1772,9 +1905,9 @@ def delete_item_live( request_options: typing.Optional[RequestOptions] = None, ) -> None: """ - Remove a live item from the site. Removing a published item will unpublish the item from the live site and set it to draft. + Unpublish a live item from the site and set the `isDraft` property to `true`. - This endpoint does not currently support bulk deletion. + For bulk unpublishing, please use [this endpoint.](/data/v2.0.0/reference/cms/collection-items/live-items/delete-items-live) Required scope | `CMS:write` @@ -1806,10 +1939,12 @@ def delete_item_live( client.collections.items.delete_item_live( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/live", + base_url=self._client_wrapper.get_environment().base, method="DELETE", params={ "cmsLocaleId": cms_locale_id, @@ -1879,6 +2014,7 @@ def update_item_live( collection_id: str, item_id: str, *, + skip_invalid_files: typing.Optional[bool] = None, id: typing.Optional[str] = OMIT, cms_locale_id: typing.Optional[str] = OMIT, last_published: typing.Optional[str] = OMIT, @@ -1902,6 +2038,9 @@ def update_item_live( item_id : str Unique identifier for an Item + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + id : typing.Optional[str] Unique identifier for the Item @@ -1943,17 +2082,22 @@ def update_item_live( client.collections.items.update_item_live( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + skip_invalid_files=True, is_archived=False, is_draft=False, field_data=CollectionItemPatchSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", ), ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/live", + base_url=self._client_wrapper.get_environment().base, method="PATCH", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "id": id, "cmsLocaleId": cms_locale_id, @@ -2008,6 +2152,16 @@ def update_item_live( ), ) ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) if _response.status_code == 429: raise TooManyRequestsError( typing.cast( @@ -2037,7 +2191,7 @@ def publish_item( self, collection_id: str, *, - item_ids: typing.Sequence[str], + request: ItemsPublishItemRequest, request_options: typing.Optional[RequestOptions] = None, ) -> ItemsPublishItemResponse: """ @@ -2050,7 +2204,7 @@ def publish_item( collection_id : str Unique identifier for a Collection - item_ids : typing.Sequence[str] + request : ItemsPublishItemRequest request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2063,24 +2217,29 @@ def publish_item( Examples -------- from webflow import Webflow + from webflow.resources.collections.resources.items import ItemIDs client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.collections.items.publish_item( collection_id="580e63fc8c9a982ac9b8b745", - item_ids=["itemIds"], + request=ItemIDs( + item_ids=[ + "643fd856d66b6528195ee2ca", + "643fd856d66b6528195ee2cb", + "643fd856d66b6528195ee2cc", + ], + ), ) """ _response = self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/publish", + base_url=self._client_wrapper.get_environment().base, method="POST", - json={ - "itemIds": item_ids, - }, - headers={ - "content-type": "application/json", - }, + json=convert_and_respect_annotation_metadata( + object_=request, annotation=ItemsPublishItemRequest, direction="write" + ), request_options=request_options, omit=OMIT, ) @@ -2168,10 +2327,11 @@ async def list_items( collection_id: str, *, cms_locale_id: typing.Optional[str] = None, - offset: typing.Optional[float] = None, - limit: typing.Optional[float] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, name: typing.Optional[str] = None, slug: typing.Optional[str] = None, + last_published: typing.Optional[ItemsListItemsRequestLastPublished] = None, sort_by: typing.Optional[ItemsListItemsRequestSortBy] = None, sort_order: typing.Optional[ItemsListItemsRequestSortOrder] = None, request_options: typing.Optional[RequestOptions] = None, @@ -2189,17 +2349,20 @@ async def list_items( cms_locale_id : typing.Optional[str] Unique identifier for a CMS Locale. This UID is different from the Site locale identifier and is listed as `cmsLocaleId` in the Sites response. To query multiple locales, input a comma separated string. - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records - limit : typing.Optional[float] + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) name : typing.Optional[str] - The name of the item(s) + Filter by the exact name of the item(s) slug : typing.Optional[str] - The slug of the item + Filter by the exact slug of the item + + last_published : typing.Optional[ItemsListItemsRequestLastPublished] + Filter by the last published date of the item(s) sort_by : typing.Optional[ItemsListItemsRequestSortBy] Sort results by the provided value @@ -2229,6 +2392,13 @@ async def list_items( async def main() -> None: await client.collections.items.list_items( collection_id="580e63fc8c9a982ac9b8b745", + cms_locale_id="cmsLocaleId", + offset=1, + limit=1, + name="name", + slug="slug", + sort_by="lastPublished", + sort_order="asc", ) @@ -2236,6 +2406,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "cmsLocaleId": cms_locale_id, @@ -2243,6 +2414,9 @@ async def main() -> None: "limit": limit, "name": name, "slug": slug, + "lastPublished": convert_and_respect_annotation_metadata( + object_=last_published, annotation=ItemsListItemsRequestLastPublished, direction="write" + ), "sortBy": sort_by, "sortOrder": sort_order, }, @@ -2316,14 +2490,15 @@ async def create_item( self, collection_id: str, *, - request: ItemsCreateItemRequest, + request: ItemsCreateItemRequestBody, + skip_invalid_files: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> CollectionItem: """ Create Item(s) in a Collection. - To create items across multiple locales, please use [this endpoint.](/v2.0.0/data/reference/cms/collection-items/staged-items/create-items) + To create items across multiple locales, please use [this endpoint.](/data/reference/cms/collection-items/staged-items/create-items) Required scope | `CMS:write` @@ -2332,7 +2507,10 @@ async def create_item( collection_id : str Unique identifier for a Collection - request : ItemsCreateItemRequest + request : ItemsCreateItemRequestBody + + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2360,12 +2538,13 @@ async def create_item( async def main() -> None: await client.collections.items.create_item( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, request=CollectionItemPostSingle( is_archived=False, is_draft=False, field_data=CollectionItemPostSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", ), ), ) @@ -2375,9 +2554,13 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items", + base_url=self._client_wrapper.get_environment().base, method="POST", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json=convert_and_respect_annotation_metadata( - object_=request, annotation=ItemsCreateItemRequest, direction="write" + object_=request, annotation=ItemsCreateItemRequestBody, direction="write" ), request_options=request_options, omit=OMIT, @@ -2450,13 +2633,13 @@ async def delete_items( self, collection_id: str, *, - items: typing.Optional[typing.Sequence[ItemsDeleteItemsRequestItemsItem]] = OMIT, + items: typing.Sequence[ItemsDeleteItemsRequestItemsItem], request_options: typing.Optional[RequestOptions] = None, ) -> None: """ Delete Items from a Collection. - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be deleted only in the primary locale. + Items will only be deleted in the primary locale unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -2465,7 +2648,7 @@ async def delete_items( collection_id : str Unique identifier for a Collection - items : typing.Optional[typing.Sequence[ItemsDeleteItemsRequestItemsItem]] + items : typing.Sequence[ItemsDeleteItemsRequestItemsItem] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2479,6 +2662,9 @@ async def delete_items( import asyncio from webflow import AsyncWebflow + from webflow.resources.collections.resources.items import ( + ItemsDeleteItemsRequestItemsItem, + ) client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -2488,6 +2674,11 @@ async def delete_items( async def main() -> None: await client.collections.items.delete_items( collection_id="580e63fc8c9a982ac9b8b745", + items=[ + ItemsDeleteItemsRequestItemsItem( + id="580e64008c9a982ac9b8b754", + ) + ], ) @@ -2495,6 +2686,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items", + base_url=self._client_wrapper.get_environment().base, method="DELETE", json={ "items": convert_and_respect_annotation_metadata( @@ -2579,13 +2771,16 @@ async def update_items( self, collection_id: str, *, + skip_invalid_files: typing.Optional[bool] = None, items: typing.Optional[typing.Sequence[CollectionItemWithIdInput]] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> CollectionItem: + ) -> ItemsUpdateItemsResponse: """ - Update a single item or multiple items (up to 100) in a Collection. + Update a single item or multiple items in a Collection. + + The limit for this endpoint is 100 items. - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be updated only in the primary locale. + Items will only be updated in the primary locale, unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -2594,6 +2789,9 @@ async def update_items( collection_id : str Unique identifier for a Collection + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + items : typing.Optional[typing.Sequence[CollectionItemWithIdInput]] request_options : typing.Optional[RequestOptions] @@ -2601,7 +2799,7 @@ async def update_items( Returns ------- - CollectionItem + ItemsUpdateItemsResponse Request was successful Examples @@ -2622,6 +2820,7 @@ async def update_items( async def main() -> None: await client.collections.items.update_items( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, items=[ CollectionItemWithIdInput( id="66f6ed9576ddacf3149d5ea6", @@ -2663,7 +2862,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items", + base_url=self._client_wrapper.get_environment().base, method="PATCH", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "items": convert_and_respect_annotation_metadata( object_=items, annotation=typing.Sequence[CollectionItemWithIdInput], direction="write" @@ -2678,9 +2881,9 @@ async def main() -> None: try: if 200 <= _response.status_code < 300: return typing.cast( - CollectionItem, + ItemsUpdateItemsResponse, parse_obj_as( - type_=CollectionItem, # type: ignore + type_=ItemsUpdateItemsResponse, # type: ignore object_=_response.json(), ), ) @@ -2744,16 +2947,21 @@ async def list_items_live( collection_id: str, *, cms_locale_id: typing.Optional[str] = None, - offset: typing.Optional[float] = None, - limit: typing.Optional[float] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, name: typing.Optional[str] = None, slug: typing.Optional[str] = None, + last_published: typing.Optional[ItemsListItemsLiveRequestLastPublished] = None, sort_by: typing.Optional[ItemsListItemsLiveRequestSortBy] = None, sort_order: typing.Optional[ItemsListItemsLiveRequestSortOrder] = None, request_options: typing.Optional[RequestOptions] = None, ) -> CollectionItemList: """ - List of all live Items within a Collection. + List all published items in a collection. + + + Serving data to applications in real-time? Use the Content Delivery API at `api-cdn.webflow.com` for better performance. The CDN-backed endpoint is optimized for high-volume reads, while the Data API is designed for writes and management operations. + Required scope | `CMS:read` @@ -2765,17 +2973,20 @@ async def list_items_live( cms_locale_id : typing.Optional[str] Unique identifier for a CMS Locale. This UID is different from the Site locale identifier and is listed as `cmsLocaleId` in the Sites response. To query multiple locales, input a comma separated string. - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records - limit : typing.Optional[float] + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) name : typing.Optional[str] - The name of the item(s) + Filter by the exact name of the item(s) slug : typing.Optional[str] - The slug of the item + Filter by the exact slug of the item + + last_published : typing.Optional[ItemsListItemsLiveRequestLastPublished] + Filter by the last published date of the item(s) sort_by : typing.Optional[ItemsListItemsLiveRequestSortBy] Sort results by the provided value @@ -2805,6 +3016,13 @@ async def list_items_live( async def main() -> None: await client.collections.items.list_items_live( collection_id="580e63fc8c9a982ac9b8b745", + cms_locale_id="cmsLocaleId", + offset=1, + limit=1, + name="name", + slug="slug", + sort_by="lastPublished", + sort_order="asc", ) @@ -2812,6 +3030,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/live", + base_url=self._client_wrapper.get_environment().data_api, method="GET", params={ "cmsLocaleId": cms_locale_id, @@ -2819,6 +3038,9 @@ async def main() -> None: "limit": limit, "name": name, "slug": slug, + "lastPublished": convert_and_respect_annotation_metadata( + object_=last_published, annotation=ItemsListItemsLiveRequestLastPublished, direction="write" + ), "sortBy": sort_by, "sortOrder": sort_order, }, @@ -2892,14 +3114,15 @@ async def create_item_live( self, collection_id: str, *, - request: ItemsCreateItemLiveRequest, + request: ItemsCreateItemLiveRequestBody, + skip_invalid_files: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> CollectionItem: """ - Create live Item(s) in a Collection. The Item(s) will be published to the live site. + Create item(s) in a collection that will be immediately published to the live site. - To create items across multiple locales, [please use this endpoint.](/v2.0.0/data/reference/cms/collection-items/staged-items/create-items) + To create items across multiple locales, [please use this endpoint.](/data/reference/cms/collection-items/staged-items/create-items) Required scope | `CMS:write` @@ -2909,7 +3132,10 @@ async def create_item_live( collection_id : str Unique identifier for a Collection - request : ItemsCreateItemLiveRequest + request : ItemsCreateItemLiveRequestBody + + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2933,12 +3159,13 @@ async def create_item_live( async def main() -> None: await client.collections.items.create_item_live( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, request=CollectionItem( is_archived=False, is_draft=False, field_data=CollectionItemFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", ), ), ) @@ -2948,9 +3175,13 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/live", + base_url=self._client_wrapper.get_environment().base, method="POST", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json=convert_and_respect_annotation_metadata( - object_=request, annotation=ItemsCreateItemLiveRequest, direction="write" + object_=request, annotation=ItemsCreateItemLiveRequestBody, direction="write" ), request_options=request_options, omit=OMIT, @@ -3023,13 +3254,13 @@ async def delete_items_live( self, collection_id: str, *, - items: typing.Optional[typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem]] = OMIT, + items: typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem], request_options: typing.Optional[RequestOptions] = None, ) -> None: """ - Remove an item or multiple items (up to 100 items) from the live site. Deleting published items will unpublish the items from the live site and set them to draft. + Unpublish up to 100 items from the live site and set the `isDraft` property to `true`. - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be unpublished only in the primary locale. + Items will only be unpublished in the primary locale unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -3038,7 +3269,7 @@ async def delete_items_live( collection_id : str Unique identifier for a Collection - items : typing.Optional[typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem]] + items : typing.Sequence[ItemsDeleteItemsLiveRequestItemsItem] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -3052,6 +3283,9 @@ async def delete_items_live( import asyncio from webflow import AsyncWebflow + from webflow.resources.collections.resources.items import ( + ItemsDeleteItemsLiveRequestItemsItem, + ) client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -3061,6 +3295,11 @@ async def delete_items_live( async def main() -> None: await client.collections.items.delete_items_live( collection_id="580e63fc8c9a982ac9b8b745", + items=[ + ItemsDeleteItemsLiveRequestItemsItem( + id="580e64008c9a982ac9b8b754", + ) + ], ) @@ -3068,6 +3307,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/live", + base_url=self._client_wrapper.get_environment().base, method="DELETE", json={ "items": convert_and_respect_annotation_metadata( @@ -3142,13 +3382,14 @@ async def update_items_live( self, collection_id: str, *, + skip_invalid_files: typing.Optional[bool] = None, items: typing.Optional[typing.Sequence[CollectionItemWithIdInput]] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> CollectionItemListNoPagination: """ - Update a single live item or multiple live items (up to 100) in a Collection + Update a single published item or multiple published items (up to 100) in a Collection - **Note:** If the `cmsLocaleId` parameter is undefined or empty and the items are localized, items will be updated only in the primary locale. + Items will only be updated in the primary locale, unless a `cmsLocaleId` is included in the request. Required scope | `CMS:write` @@ -3157,6 +3398,9 @@ async def update_items_live( collection_id : str Unique identifier for a Collection + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + items : typing.Optional[typing.Sequence[CollectionItemWithIdInput]] request_options : typing.Optional[RequestOptions] @@ -3185,6 +3429,7 @@ async def update_items_live( async def main() -> None: await client.collections.items.update_items_live( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, items=[ CollectionItemWithIdInput( id="66f6ed9576ddacf3149d5ea6", @@ -3226,7 +3471,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/live", + base_url=self._client_wrapper.get_environment().base, method="PATCH", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "items": convert_and_respect_annotation_metadata( object_=items, annotation=typing.Sequence[CollectionItemWithIdInput], direction="write" @@ -3277,6 +3526,16 @@ async def main() -> None: ), ) ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) if _response.status_code == 429: raise TooManyRequestsError( typing.cast( @@ -3307,6 +3566,7 @@ async def create_items( collection_id: str, *, field_data: CreateBulkCollectionItemRequestBodyFieldData, + skip_invalid_files: typing.Optional[bool] = None, cms_locale_ids: typing.Optional[typing.Sequence[str]] = OMIT, is_archived: typing.Optional[bool] = OMIT, is_draft: typing.Optional[bool] = OMIT, @@ -3315,9 +3575,10 @@ async def create_items( """ Create an item or multiple items in a CMS Collection across multiple corresponding locales. - **Notes:** + - This endpoint can create up to 100 items in a request. - - If the `cmsLocaleIds` parameter is undefined or empty and localization is enabled, items will only be created in the primary locale. + - If the `cmsLocaleIds` parameter is not included in the request, an item will only be created in the primary locale. + Required scope | `CMS:write` @@ -3328,6 +3589,9 @@ async def create_items( field_data : CreateBulkCollectionItemRequestBodyFieldData + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + cms_locale_ids : typing.Optional[typing.Sequence[str]] Array of identifiers for the locales where the item will be created @@ -3360,6 +3624,7 @@ async def create_items( async def main() -> None: await client.collections.items.create_items( collection_id="580e63fc8c9a982ac9b8b745", + skip_invalid_files=True, cms_locale_ids=[ "66f6e966c9e1dc700a857ca3", "66f6e966c9e1dc700a857ca4", @@ -3378,7 +3643,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/bulk", + base_url=self._client_wrapper.get_environment().base, method="POST", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "cmsLocaleIds": cms_locale_ids, "isArchived": is_archived, @@ -3504,6 +3773,7 @@ async def main() -> None: await client.collections.items.get_item( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) @@ -3511,6 +3781,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "cmsLocaleId": cms_locale_id, @@ -3590,7 +3861,7 @@ async def delete_item( request_options: typing.Optional[RequestOptions] = None, ) -> None: """ - Delete an Item from a Collection. This endpoint does not currently support bulk deletion. + Delete an item from a collection. Required scope | `CMS:write` @@ -3627,6 +3898,7 @@ async def main() -> None: await client.collections.items.delete_item( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) @@ -3634,6 +3906,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", params={ "cmsLocaleId": cms_locale_id, @@ -3703,6 +3976,7 @@ async def update_item( collection_id: str, item_id: str, *, + skip_invalid_files: typing.Optional[bool] = None, id: typing.Optional[str] = OMIT, cms_locale_id: typing.Optional[str] = OMIT, last_published: typing.Optional[str] = OMIT, @@ -3726,6 +4000,9 @@ async def update_item( item_id : str Unique identifier for an Item + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + id : typing.Optional[str] Unique identifier for the Item @@ -3772,11 +4049,12 @@ async def main() -> None: await client.collections.items.update_item( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + skip_invalid_files=True, is_archived=False, is_draft=False, field_data=CollectionItemPatchSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", ), ) @@ -3785,7 +4063,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "id": id, "cmsLocaleId": cms_locale_id, @@ -3876,6 +4158,10 @@ async def get_item_live( """ Get details of a selected Collection live Item. + + Serving data to applications in real-time? Use the Content Delivery API at `api-cdn.webflow.com` for better performance. The CDN-backed endpoint is optimized for high-volume reads, while the Data API is designed for writes and management operations. + + Required scope | `CMS:read` Parameters @@ -3912,6 +4198,7 @@ async def main() -> None: await client.collections.items.get_item_live( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) @@ -3919,6 +4206,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/live", + base_url=self._client_wrapper.get_environment().data_api, method="GET", params={ "cmsLocaleId": cms_locale_id, @@ -3998,9 +4286,9 @@ async def delete_item_live( request_options: typing.Optional[RequestOptions] = None, ) -> None: """ - Remove a live item from the site. Removing a published item will unpublish the item from the live site and set it to draft. + Unpublish a live item from the site and set the `isDraft` property to `true`. - This endpoint does not currently support bulk deletion. + For bulk unpublishing, please use [this endpoint.](/data/v2.0.0/reference/cms/collection-items/live-items/delete-items-live) Required scope | `CMS:write` @@ -4037,6 +4325,7 @@ async def main() -> None: await client.collections.items.delete_item_live( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + cms_locale_id="cmsLocaleId", ) @@ -4044,6 +4333,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/live", + base_url=self._client_wrapper.get_environment().base, method="DELETE", params={ "cmsLocaleId": cms_locale_id, @@ -4113,6 +4403,7 @@ async def update_item_live( collection_id: str, item_id: str, *, + skip_invalid_files: typing.Optional[bool] = None, id: typing.Optional[str] = OMIT, cms_locale_id: typing.Optional[str] = OMIT, last_published: typing.Optional[str] = OMIT, @@ -4136,6 +4427,9 @@ async def update_item_live( item_id : str Unique identifier for an Item + skip_invalid_files : typing.Optional[bool] + When true, invalid files are skipped and processing continues. When false, the entire request fails if any file is invalid. + id : typing.Optional[str] Unique identifier for the Item @@ -4182,11 +4476,12 @@ async def main() -> None: await client.collections.items.update_item_live( collection_id="580e63fc8c9a982ac9b8b745", item_id="580e64008c9a982ac9b8b754", + skip_invalid_files=True, is_archived=False, is_draft=False, field_data=CollectionItemPatchSingleFieldData( - name="Pan Galactic Gargle Blaster Recipe", - slug="pan-galactic-gargle-blaster", + name="The Hitchhiker's Guide to the Galaxy", + slug="hitchhikers-guide-to-the-galaxy", ), ) @@ -4195,7 +4490,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/live", + base_url=self._client_wrapper.get_environment().base, method="PATCH", + params={ + "skipInvalidFiles": skip_invalid_files, + }, json={ "id": id, "cmsLocaleId": cms_locale_id, @@ -4250,6 +4549,16 @@ async def main() -> None: ), ) ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) if _response.status_code == 429: raise TooManyRequestsError( typing.cast( @@ -4279,7 +4588,7 @@ async def publish_item( self, collection_id: str, *, - item_ids: typing.Sequence[str], + request: ItemsPublishItemRequest, request_options: typing.Optional[RequestOptions] = None, ) -> ItemsPublishItemResponse: """ @@ -4292,7 +4601,7 @@ async def publish_item( collection_id : str Unique identifier for a Collection - item_ids : typing.Sequence[str] + request : ItemsPublishItemRequest request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -4307,6 +4616,7 @@ async def publish_item( import asyncio from webflow import AsyncWebflow + from webflow.resources.collections.resources.items import ItemIDs client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -4316,7 +4626,13 @@ async def publish_item( async def main() -> None: await client.collections.items.publish_item( collection_id="580e63fc8c9a982ac9b8b745", - item_ids=["itemIds"], + request=ItemIDs( + item_ids=[ + "643fd856d66b6528195ee2ca", + "643fd856d66b6528195ee2cb", + "643fd856d66b6528195ee2cc", + ], + ), ) @@ -4324,13 +4640,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"collections/{jsonable_encoder(collection_id)}/items/publish", + base_url=self._client_wrapper.get_environment().base, method="POST", - json={ - "itemIds": item_ids, - }, - headers={ - "content-type": "application/json", - }, + json=convert_and_respect_annotation_metadata( + object_=request, annotation=ItemsPublishItemRequest, direction="write" + ), request_options=request_options, omit=OMIT, ) diff --git a/src/webflow/resources/collections/resources/items/types/__init__.py b/src/webflow/resources/collections/resources/items/types/__init__.py index 67040fb..2d9a604 100644 --- a/src/webflow/resources/collections/resources/items/types/__init__.py +++ b/src/webflow/resources/collections/resources/items/types/__init__.py @@ -2,15 +2,20 @@ from .create_bulk_collection_item_request_body_field_data import CreateBulkCollectionItemRequestBodyFieldData from .create_bulk_collection_item_request_body_field_data_item import CreateBulkCollectionItemRequestBodyFieldDataItem -from .items_create_item_live_request import ItemsCreateItemLiveRequest -from .items_create_item_request import ItemsCreateItemRequest +from .item_i_ds import ItemIDs +from .item_i_ds_with_locales import ItemIDsWithLocales +from .items_create_item_live_request_body import ItemsCreateItemLiveRequestBody +from .items_create_item_request_body import ItemsCreateItemRequestBody from .items_delete_items_live_request_items_item import ItemsDeleteItemsLiveRequestItemsItem from .items_delete_items_request_items_item import ItemsDeleteItemsRequestItemsItem from .items_list_items_live_request_sort_by import ItemsListItemsLiveRequestSortBy from .items_list_items_live_request_sort_order import ItemsListItemsLiveRequestSortOrder from .items_list_items_request_sort_by import ItemsListItemsRequestSortBy from .items_list_items_request_sort_order import ItemsListItemsRequestSortOrder +from .items_publish_item_request import ItemsPublishItemRequest +from .items_publish_item_request_items_items_item import ItemsPublishItemRequestItemsItemsItem from .items_publish_item_response import ItemsPublishItemResponse +from .items_update_items_response import ItemsUpdateItemsResponse from .multiple_items import MultipleItems from .multiple_live_items import MultipleLiveItems from .single_cms_item import SingleCmsItem @@ -18,15 +23,20 @@ __all__ = [ "CreateBulkCollectionItemRequestBodyFieldData", "CreateBulkCollectionItemRequestBodyFieldDataItem", - "ItemsCreateItemLiveRequest", - "ItemsCreateItemRequest", + "ItemIDs", + "ItemIDsWithLocales", + "ItemsCreateItemLiveRequestBody", + "ItemsCreateItemRequestBody", "ItemsDeleteItemsLiveRequestItemsItem", "ItemsDeleteItemsRequestItemsItem", "ItemsListItemsLiveRequestSortBy", "ItemsListItemsLiveRequestSortOrder", "ItemsListItemsRequestSortBy", "ItemsListItemsRequestSortOrder", + "ItemsPublishItemRequest", + "ItemsPublishItemRequestItemsItemsItem", "ItemsPublishItemResponse", + "ItemsUpdateItemsResponse", "MultipleItems", "MultipleLiveItems", "SingleCmsItem", diff --git a/src/webflow/resources/collections/resources/items/types/item_i_ds.py b/src/webflow/resources/collections/resources/items/types/item_i_ds.py new file mode 100644 index 0000000..b9b138e --- /dev/null +++ b/src/webflow/resources/collections/resources/items/types/item_i_ds.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +from ......core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ......core.serialization import FieldMetadata +from ......core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class ItemIDs(UniversalBaseModel): + """ + An array of Item IDs in a single locale + """ + + item_ids: typing_extensions.Annotated[typing.Optional[typing.List[str]], FieldMetadata(alias="itemIds")] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/collections/resources/items/types/item_i_ds_with_locales.py b/src/webflow/resources/collections/resources/items/types/item_i_ds_with_locales.py new file mode 100644 index 0000000..ba98ae7 --- /dev/null +++ b/src/webflow/resources/collections/resources/items/types/item_i_ds_with_locales.py @@ -0,0 +1,24 @@ +# This file was auto-generated by Fern from our API Definition. + +from ......core.pydantic_utilities import UniversalBaseModel +import typing +from .items_publish_item_request_items_items_item import ItemsPublishItemRequestItemsItemsItem +from ......core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class ItemIDsWithLocales(UniversalBaseModel): + """ + An array of Item IDs with included `cmsLocaleIds` + """ + + items: typing.Optional[typing.List[ItemsPublishItemRequestItemsItemsItem]] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/collections/resources/items/types/items_create_item_live_request.py b/src/webflow/resources/collections/resources/items/types/items_create_item_live_request_body.py similarity index 69% rename from src/webflow/resources/collections/resources/items/types/items_create_item_live_request.py rename to src/webflow/resources/collections/resources/items/types/items_create_item_live_request_body.py index dc2f963..348e0be 100644 --- a/src/webflow/resources/collections/resources/items/types/items_create_item_live_request.py +++ b/src/webflow/resources/collections/resources/items/types/items_create_item_live_request_body.py @@ -4,4 +4,4 @@ from ......types.collection_item import CollectionItem from .multiple_live_items import MultipleLiveItems -ItemsCreateItemLiveRequest = typing.Union[CollectionItem, MultipleLiveItems] +ItemsCreateItemLiveRequestBody = typing.Union[CollectionItem, MultipleLiveItems] diff --git a/src/webflow/resources/collections/resources/items/types/items_create_item_request.py b/src/webflow/resources/collections/resources/items/types/items_create_item_request_body.py similarity index 70% rename from src/webflow/resources/collections/resources/items/types/items_create_item_request.py rename to src/webflow/resources/collections/resources/items/types/items_create_item_request_body.py index 7627c55..af4860a 100644 --- a/src/webflow/resources/collections/resources/items/types/items_create_item_request.py +++ b/src/webflow/resources/collections/resources/items/types/items_create_item_request_body.py @@ -4,4 +4,4 @@ from ......types.collection_item_post_single import CollectionItemPostSingle from .multiple_items import MultipleItems -ItemsCreateItemRequest = typing.Union[CollectionItemPostSingle, MultipleItems] +ItemsCreateItemRequestBody = typing.Union[CollectionItemPostSingle, MultipleItems] diff --git a/src/webflow/resources/collections/resources/items/types/items_delete_items_live_request_items_item.py b/src/webflow/resources/collections/resources/items/types/items_delete_items_live_request_items_item.py index 63e00bc..544df88 100644 --- a/src/webflow/resources/collections/resources/items/types/items_delete_items_live_request_items_item.py +++ b/src/webflow/resources/collections/resources/items/types/items_delete_items_live_request_items_item.py @@ -1,15 +1,15 @@ # This file was auto-generated by Fern from our API Definition. from ......core.pydantic_utilities import UniversalBaseModel -import typing_extensions -from ......core.serialization import FieldMetadata import pydantic +import typing_extensions import typing +from ......core.serialization import FieldMetadata from ......core.pydantic_utilities import IS_PYDANTIC_V2 class ItemsDeleteItemsLiveRequestItemsItem(UniversalBaseModel): - item_id: typing_extensions.Annotated[str, FieldMetadata(alias="itemId")] = pydantic.Field() + id: str = pydantic.Field() """ Unique identifier for the Item """ diff --git a/src/webflow/resources/collections/resources/items/types/items_publish_item_request.py b/src/webflow/resources/collections/resources/items/types/items_publish_item_request.py new file mode 100644 index 0000000..4f7a82b --- /dev/null +++ b/src/webflow/resources/collections/resources/items/types/items_publish_item_request.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from .item_i_ds import ItemIDs +from .item_i_ds_with_locales import ItemIDsWithLocales + +ItemsPublishItemRequest = typing.Union[ItemIDs, ItemIDsWithLocales] diff --git a/src/webflow/resources/collections/resources/items/types/items_publish_item_request_items_items_item.py b/src/webflow/resources/collections/resources/items/types/items_publish_item_request_items_items_item.py new file mode 100644 index 0000000..08b2e17 --- /dev/null +++ b/src/webflow/resources/collections/resources/items/types/items_publish_item_request_items_items_item.py @@ -0,0 +1,31 @@ +# This file was auto-generated by Fern from our API Definition. + +from ......core.pydantic_utilities import UniversalBaseModel +import pydantic +import typing_extensions +import typing +from ......core.serialization import FieldMetadata +from ......core.pydantic_utilities import IS_PYDANTIC_V2 + + +class ItemsPublishItemRequestItemsItemsItem(UniversalBaseModel): + id: str = pydantic.Field() + """ + The ID of the CMS item + """ + + cms_locale_ids: typing_extensions.Annotated[ + typing.Optional[typing.List[str]], FieldMetadata(alias="cmsLocaleIds") + ] = pydantic.Field(default=None) + """ + Array of identifiers for the locales where the item will be published + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/collections/resources/items/types/items_update_items_response.py b/src/webflow/resources/collections/resources/items/types/items_update_items_response.py new file mode 100644 index 0000000..c073f18 --- /dev/null +++ b/src/webflow/resources/collections/resources/items/types/items_update_items_response.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from ......types.collection_item import CollectionItem +from ......types.collection_item_list import CollectionItemList + +ItemsUpdateItemsResponse = typing.Union[CollectionItem, CollectionItemList] diff --git a/src/webflow/resources/components/client.py b/src/webflow/resources/components/client.py index ef50ac9..5437017 100644 --- a/src/webflow/resources/components/client.py +++ b/src/webflow/resources/components/client.py @@ -36,8 +36,9 @@ def list( self, site_id: str, *, - limit: typing.Optional[float] = None, - offset: typing.Optional[float] = None, + branch_id: typing.Optional[str] = None, + limit: typing.Optional[int] = None, + offset: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ComponentList: """ @@ -50,10 +51,13 @@ def list( site_id : str Unique identifier for a Site - limit : typing.Optional[float] + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. + + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records request_options : typing.Optional[RequestOptions] @@ -73,12 +77,17 @@ def list( ) client.components.list( site_id="580e63e98c9a982ac9b8b741", + branch_id="68026fa68ef6dc744c75b833", + limit=1, + offset=1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ + "branchId": branch_id, "limit": limit, "offset": offset, }, @@ -154,12 +163,13 @@ def get_content( component_id: str, *, locale_id: typing.Optional[str] = None, - limit: typing.Optional[float] = None, - offset: typing.Optional[float] = None, + branch_id: typing.Optional[str] = None, + limit: typing.Optional[int] = None, + offset: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ComponentDom: """ - Get static content from a component definition. This includes text nodes, image nodes and nested component instances. + Get static content from a component definition. This includes text nodes, image nodes, select nodes, text input nodes, submit button nodes, and nested component instances. To retrieve dynamic content set by component properties, use the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint. If you do not provide a Locale ID in your request, the response will return any content that can be localized from the Primary locale. @@ -175,12 +185,17 @@ def get_content( Unique identifier for a Component locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) - limit : typing.Optional[float] + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. + + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records request_options : typing.Optional[RequestOptions] @@ -202,13 +217,18 @@ def get_content( site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", + limit=1, + offset=1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components/{jsonable_encoder(component_id)}/dom", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, + "branchId": branch_id, "limit": limit, "offset": offset, }, @@ -285,14 +305,16 @@ def update_content( *, nodes: typing.Sequence[ComponentDomWriteNodesItem], locale_id: typing.Optional[str] = None, + branch_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ComponentsUpdateContentResponse: """ This endpoint updates content within a component defintion for **secondary locales**. It supports updating up to 1000 nodes in a single request. Before making updates: - 1. Use the [get component content](/data/reference/pages-and-components/components/get-content) endpoint to identify available content nodes and their types - 2. If your component definition has a component instance nested within it, retrieve the nested component instance's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint + 1. Use the [get component content](/data/reference/pages-and-components/components/get-content) endpoint to identify available content nodes and their types. + 2. If your component definition has a component instance nested within it, retrieve the nested component instance's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint. + 3. DOM elements may include a `data-w-id` attribute. This attribute is used by Webflow to maintain custom attributes and links across locales. Always include the original `data-w-id` value in your update requests to ensure consistent behavior across all locales. This endpoint is specifically for localizing component definitions. Ensure that the specified `localeId` is a valid **secondary locale** for the site otherwise the request will fail. @@ -312,7 +334,12 @@ def update_content( List of DOM Nodes with the new content that will be updated in each node. locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -327,6 +354,10 @@ def update_content( from webflow import ( ComponentInstanceNodePropertyOverridesWrite, ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem, + Select, + SelectNodeWriteChoicesItem, + SubmitButtonNodeWrite, + TextInputNodeWrite, TextNodeWrite, Webflow, ) @@ -338,6 +369,7 @@ def update_content( site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", nodes=[ TextNodeWrite( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad623", @@ -347,6 +379,28 @@ def update_content( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad627", text="

Don't Panic!

Always know where your towel is.

", ), + Select( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad635", + choices=[ + SelectNodeWriteChoicesItem( + value="choice-1", + text="First choice", + ), + SelectNodeWriteChoicesItem( + value="choice-2", + text="Second choice", + ), + ], + ), + TextInputNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad642", + placeholder="Enter something here...", + ), + SubmitButtonNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad671", + value="Submit", + waiting_text="Submitting...", + ), ComponentInstanceNodePropertyOverridesWrite( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad629", property_overrides=[ @@ -365,9 +419,11 @@ def update_content( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components/{jsonable_encoder(component_id)}/dom", + base_url=self._client_wrapper.get_environment().base, method="POST", params={ "localeId": locale_id, + "branchId": branch_id, }, json={ "nodes": convert_and_respect_annotation_metadata( @@ -460,14 +516,15 @@ def get_properties( component_id: str, *, locale_id: typing.Optional[str] = None, - limit: typing.Optional[float] = None, - offset: typing.Optional[float] = None, + branch_id: typing.Optional[str] = None, + limit: typing.Optional[int] = None, + offset: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ComponentProperties: """ - Get the property default values of a component definition. + Get the default property values of a component definition. - If you do not provide a Locale ID in your request, the response will return any properties that can be localized from the Primary locale. + If you do not include a `localeId` in your request, the response will return any properties that can be localized from the Primary locale. Required scope | `components:read` @@ -480,12 +537,17 @@ def get_properties( Unique identifier for a Component locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) - limit : typing.Optional[float] + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. + + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records request_options : typing.Optional[RequestOptions] @@ -507,13 +569,18 @@ def get_properties( site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", + limit=1, + offset=1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components/{jsonable_encoder(component_id)}/properties", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, + "branchId": branch_id, "limit": limit, "offset": offset, }, @@ -590,15 +657,17 @@ def update_properties( *, properties: typing.Sequence[ComponentPropertiesWritePropertiesItem], locale_id: typing.Optional[str] = None, + branch_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ComponentsUpdatePropertiesResponse: """ - Update the property default values of a component definition in a specificed locale. + Update the default property values of a component definition in a specificed locale. Before making updates: - 1. Use the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint to identify available properties + 1. Use the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint to identify properties that can be updated in a secondary locale. + 2. Rich Text properties may include a `data-w-id` attribute. This attribute is used by Webflow to maintain links across locales. Always include the original `data-w-id` value in your update requests to ensure consistent behavior across all locales. - The request requires a secondary locale ID. If a locale is missing, the request will not be processed and will result in an error. + The request requires a secondary locale ID. If a `localeId` is missing, the request will not be processed and will result in an error. Required scope | `components:write` @@ -614,7 +683,12 @@ def update_properties( A list of component properties to update within the specified secondary locale. locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -636,6 +710,7 @@ def update_properties( site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", properties=[ ComponentPropertiesWritePropertiesItem( property_id="a245c12d-995b-55ee-5ec7-aa36a6cad623", @@ -650,9 +725,11 @@ def update_properties( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components/{jsonable_encoder(component_id)}/properties", + base_url=self._client_wrapper.get_environment().base, method="POST", params={ "localeId": locale_id, + "branchId": branch_id, }, json={ "properties": convert_and_respect_annotation_metadata( @@ -740,8 +817,9 @@ async def list( self, site_id: str, *, - limit: typing.Optional[float] = None, - offset: typing.Optional[float] = None, + branch_id: typing.Optional[str] = None, + limit: typing.Optional[int] = None, + offset: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ComponentList: """ @@ -754,10 +832,13 @@ async def list( site_id : str Unique identifier for a Site - limit : typing.Optional[float] + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. + + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records request_options : typing.Optional[RequestOptions] @@ -782,6 +863,9 @@ async def list( async def main() -> None: await client.components.list( site_id="580e63e98c9a982ac9b8b741", + branch_id="68026fa68ef6dc744c75b833", + limit=1, + offset=1, ) @@ -789,8 +873,10 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ + "branchId": branch_id, "limit": limit, "offset": offset, }, @@ -866,12 +952,13 @@ async def get_content( component_id: str, *, locale_id: typing.Optional[str] = None, - limit: typing.Optional[float] = None, - offset: typing.Optional[float] = None, + branch_id: typing.Optional[str] = None, + limit: typing.Optional[int] = None, + offset: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ComponentDom: """ - Get static content from a component definition. This includes text nodes, image nodes and nested component instances. + Get static content from a component definition. This includes text nodes, image nodes, select nodes, text input nodes, submit button nodes, and nested component instances. To retrieve dynamic content set by component properties, use the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint. If you do not provide a Locale ID in your request, the response will return any content that can be localized from the Primary locale. @@ -887,12 +974,17 @@ async def get_content( Unique identifier for a Component locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) - limit : typing.Optional[float] + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. + + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records request_options : typing.Optional[RequestOptions] @@ -919,6 +1011,9 @@ async def main() -> None: site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", + limit=1, + offset=1, ) @@ -926,9 +1021,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components/{jsonable_encoder(component_id)}/dom", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, + "branchId": branch_id, "limit": limit, "offset": offset, }, @@ -1005,14 +1102,16 @@ async def update_content( *, nodes: typing.Sequence[ComponentDomWriteNodesItem], locale_id: typing.Optional[str] = None, + branch_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ComponentsUpdateContentResponse: """ This endpoint updates content within a component defintion for **secondary locales**. It supports updating up to 1000 nodes in a single request. Before making updates: - 1. Use the [get component content](/data/reference/pages-and-components/components/get-content) endpoint to identify available content nodes and their types - 2. If your component definition has a component instance nested within it, retrieve the nested component instance's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint + 1. Use the [get component content](/data/reference/pages-and-components/components/get-content) endpoint to identify available content nodes and their types. + 2. If your component definition has a component instance nested within it, retrieve the nested component instance's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint. + 3. DOM elements may include a `data-w-id` attribute. This attribute is used by Webflow to maintain custom attributes and links across locales. Always include the original `data-w-id` value in your update requests to ensure consistent behavior across all locales. This endpoint is specifically for localizing component definitions. Ensure that the specified `localeId` is a valid **secondary locale** for the site otherwise the request will fail. @@ -1032,7 +1131,12 @@ async def update_content( List of DOM Nodes with the new content that will be updated in each node. locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1050,6 +1154,10 @@ async def update_content( AsyncWebflow, ComponentInstanceNodePropertyOverridesWrite, ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem, + Select, + SelectNodeWriteChoicesItem, + SubmitButtonNodeWrite, + TextInputNodeWrite, TextNodeWrite, ) @@ -1063,6 +1171,7 @@ async def main() -> None: site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", nodes=[ TextNodeWrite( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad623", @@ -1072,6 +1181,28 @@ async def main() -> None: node_id="a245c12d-995b-55ee-5ec7-aa36a6cad627", text="

Don't Panic!

Always know where your towel is.

", ), + Select( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad635", + choices=[ + SelectNodeWriteChoicesItem( + value="choice-1", + text="First choice", + ), + SelectNodeWriteChoicesItem( + value="choice-2", + text="Second choice", + ), + ], + ), + TextInputNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad642", + placeholder="Enter something here...", + ), + SubmitButtonNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad671", + value="Submit", + waiting_text="Submitting...", + ), ComponentInstanceNodePropertyOverridesWrite( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad629", property_overrides=[ @@ -1093,9 +1224,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components/{jsonable_encoder(component_id)}/dom", + base_url=self._client_wrapper.get_environment().base, method="POST", params={ "localeId": locale_id, + "branchId": branch_id, }, json={ "nodes": convert_and_respect_annotation_metadata( @@ -1188,14 +1321,15 @@ async def get_properties( component_id: str, *, locale_id: typing.Optional[str] = None, - limit: typing.Optional[float] = None, - offset: typing.Optional[float] = None, + branch_id: typing.Optional[str] = None, + limit: typing.Optional[int] = None, + offset: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ComponentProperties: """ - Get the property default values of a component definition. + Get the default property values of a component definition. - If you do not provide a Locale ID in your request, the response will return any properties that can be localized from the Primary locale. + If you do not include a `localeId` in your request, the response will return any properties that can be localized from the Primary locale. Required scope | `components:read` @@ -1208,12 +1342,17 @@ async def get_properties( Unique identifier for a Component locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) - limit : typing.Optional[float] + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. + + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records request_options : typing.Optional[RequestOptions] @@ -1240,6 +1379,9 @@ async def main() -> None: site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", + limit=1, + offset=1, ) @@ -1247,9 +1389,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components/{jsonable_encoder(component_id)}/properties", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, + "branchId": branch_id, "limit": limit, "offset": offset, }, @@ -1326,15 +1470,17 @@ async def update_properties( *, properties: typing.Sequence[ComponentPropertiesWritePropertiesItem], locale_id: typing.Optional[str] = None, + branch_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ComponentsUpdatePropertiesResponse: """ - Update the property default values of a component definition in a specificed locale. + Update the default property values of a component definition in a specificed locale. Before making updates: - 1. Use the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint to identify available properties + 1. Use the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint to identify properties that can be updated in a secondary locale. + 2. Rich Text properties may include a `data-w-id` attribute. This attribute is used by Webflow to maintain links across locales. Always include the original `data-w-id` value in your update requests to ensure consistent behavior across all locales. - The request requires a secondary locale ID. If a locale is missing, the request will not be processed and will result in an error. + The request requires a secondary locale ID. If a `localeId` is missing, the request will not be processed and will result in an error. Required scope | `components:write` @@ -1350,7 +1496,12 @@ async def update_properties( A list of component properties to update within the specified secondary locale. locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + branch_id : typing.Optional[str] + Scope the operation to work on a specific branch. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1377,6 +1528,7 @@ async def main() -> None: site_id="580e63e98c9a982ac9b8b741", component_id="8505ba55-ef72-629e-f85c-33e4b703d48b", locale_id="65427cf400e02b306eaa04a0", + branch_id="68026fa68ef6dc744c75b833", properties=[ ComponentPropertiesWritePropertiesItem( property_id="a245c12d-995b-55ee-5ec7-aa36a6cad623", @@ -1394,9 +1546,11 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/components/{jsonable_encoder(component_id)}/properties", + base_url=self._client_wrapper.get_environment().base, method="POST", params={ "localeId": locale_id, + "branchId": branch_id, }, json={ "properties": convert_and_respect_annotation_metadata( diff --git a/src/webflow/resources/components/types/component_dom_write_nodes_item.py b/src/webflow/resources/components/types/component_dom_write_nodes_item.py index 27888e6..1b1789c 100644 --- a/src/webflow/resources/components/types/component_dom_write_nodes_item.py +++ b/src/webflow/resources/components/types/component_dom_write_nodes_item.py @@ -3,5 +3,16 @@ import typing from ....types.text_node_write import TextNodeWrite from ....types.component_instance_node_property_overrides_write import ComponentInstanceNodePropertyOverridesWrite +from ....types.select import Select +from ....types.text_input_node_write import TextInputNodeWrite +from ....types.submit_button_node_write import SubmitButtonNodeWrite +from ....types.search_button_node_write import SearchButtonNodeWrite -ComponentDomWriteNodesItem = typing.Union[TextNodeWrite, ComponentInstanceNodePropertyOverridesWrite] +ComponentDomWriteNodesItem = typing.Union[ + TextNodeWrite, + ComponentInstanceNodePropertyOverridesWrite, + Select, + TextInputNodeWrite, + SubmitButtonNodeWrite, + SearchButtonNodeWrite, +] diff --git a/src/webflow/resources/ecommerce/client.py b/src/webflow/resources/ecommerce/client.py index bbd3a5d..04ddba6 100644 --- a/src/webflow/resources/ecommerce/client.py +++ b/src/webflow/resources/ecommerce/client.py @@ -57,6 +57,7 @@ def get_settings( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/ecommerce/settings", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -191,6 +192,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/ecommerce/settings", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) diff --git a/src/webflow/resources/forms/client.py b/src/webflow/resources/forms/client.py index 515b631..40741cb 100644 --- a/src/webflow/resources/forms/client.py +++ b/src/webflow/resources/forms/client.py @@ -33,8 +33,8 @@ def list( self, site_id: str, *, - limit: typing.Optional[float] = None, - offset: typing.Optional[float] = None, + limit: typing.Optional[int] = None, + offset: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> FormList: """ @@ -47,10 +47,10 @@ def list( site_id : str Unique identifier for a Site - limit : typing.Optional[float] + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records request_options : typing.Optional[RequestOptions] @@ -70,10 +70,13 @@ def list( ) client.forms.list( site_id="580e63e98c9a982ac9b8b741", + limit=1, + offset=1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/forms", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "limit": limit, @@ -197,6 +200,7 @@ def get(self, form_id: str, *, request_options: typing.Optional[RequestOptions] """ _response = self._client_wrapper.httpx_client.request( f"forms/{jsonable_encoder(form_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -278,13 +282,19 @@ def list_submissions( self, form_id: str, *, - offset: typing.Optional[float] = None, - limit: typing.Optional[float] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> FormSubmissionList: """ List form submissions for a given form + + When a form is used in a component definition, each instance of the form is considered a unique form. + + To get a combined list of submissions for a form that appears across multiple component instances, use the [List Form Submissions by Site](/data/reference/forms/form-submissions/list-submissions-by-site) endpoint. + + Required scope | `forms:read` Parameters @@ -292,10 +302,10 @@ def list_submissions( form_id : str Unique identifier for a Form - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records - limit : typing.Optional[float] + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) request_options : typing.Optional[RequestOptions] @@ -315,10 +325,13 @@ def list_submissions( ) client.forms.list_submissions( form_id="580e63e98c9a982ac9b8b741", + offset=1, + limit=1, ) """ _response = self._client_wrapper.httpx_client.request( f"forms/{jsonable_encoder(form_id)}/submissions", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "offset": offset, @@ -434,6 +447,7 @@ def get_submission( """ _response = self._client_wrapper.httpx_client.request( f"form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -511,6 +525,122 @@ def get_submission( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) + def delete_submission( + self, form_submission_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + Delete a form submission + + + Required scope | `forms:write` + + Parameters + ---------- + form_submission_id : str + Unique identifier for a Form Submission + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.forms.delete_submission( + form_submission_id="580e63e98c9a982ac9b8b741", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 403: + raise ForbiddenError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + def update_submission( self, form_submission_id: str, @@ -552,6 +682,7 @@ def update_submission( """ _response = self._client_wrapper.httpx_client.request( f"form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "formSubmissionData": form_submission_data, @@ -655,8 +786,8 @@ async def list( self, site_id: str, *, - limit: typing.Optional[float] = None, - offset: typing.Optional[float] = None, + limit: typing.Optional[int] = None, + offset: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> FormList: """ @@ -669,10 +800,10 @@ async def list( site_id : str Unique identifier for a Site - limit : typing.Optional[float] + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records request_options : typing.Optional[RequestOptions] @@ -697,6 +828,8 @@ async def list( async def main() -> None: await client.forms.list( site_id="580e63e98c9a982ac9b8b741", + limit=1, + offset=1, ) @@ -704,6 +837,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/forms", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "limit": limit, @@ -835,6 +969,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"forms/{jsonable_encoder(form_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -916,13 +1051,19 @@ async def list_submissions( self, form_id: str, *, - offset: typing.Optional[float] = None, - limit: typing.Optional[float] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> FormSubmissionList: """ List form submissions for a given form + + When a form is used in a component definition, each instance of the form is considered a unique form. + + To get a combined list of submissions for a form that appears across multiple component instances, use the [List Form Submissions by Site](/data/reference/forms/form-submissions/list-submissions-by-site) endpoint. + + Required scope | `forms:read` Parameters @@ -930,10 +1071,10 @@ async def list_submissions( form_id : str Unique identifier for a Form - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records - limit : typing.Optional[float] + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) request_options : typing.Optional[RequestOptions] @@ -958,6 +1099,8 @@ async def list_submissions( async def main() -> None: await client.forms.list_submissions( form_id="580e63e98c9a982ac9b8b741", + offset=1, + limit=1, ) @@ -965,6 +1108,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"forms/{jsonable_encoder(form_id)}/submissions", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "offset": offset, @@ -1088,6 +1232,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -1165,6 +1310,130 @@ async def main() -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) + async def delete_submission( + self, form_submission_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + Delete a form submission + + + Required scope | `forms:write` + + Parameters + ---------- + form_submission_id : str + Unique identifier for a Form Submission + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.forms.delete_submission( + form_submission_id="580e63e98c9a982ac9b8b741", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 403: + raise ForbiddenError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + async def update_submission( self, form_submission_id: str, @@ -1214,6 +1483,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "formSubmissionData": form_submission_data, diff --git a/src/webflow/resources/inventory/__init__.py b/src/webflow/resources/inventory/__init__.py index f95deee..e76ae2e 100644 --- a/src/webflow/resources/inventory/__init__.py +++ b/src/webflow/resources/inventory/__init__.py @@ -1,5 +1,5 @@ # This file was auto-generated by Fern from our API Definition. -from .types import InventoryUpdateRequestInventoryType +from .types import EcommInventoryChangedPayload, InventoryUpdateRequestInventoryType -__all__ = ["InventoryUpdateRequestInventoryType"] +__all__ = ["EcommInventoryChangedPayload", "InventoryUpdateRequestInventoryType"] diff --git a/src/webflow/resources/inventory/client.py b/src/webflow/resources/inventory/client.py index 27e4f3c..db582a9 100644 --- a/src/webflow/resources/inventory/client.py +++ b/src/webflow/resources/inventory/client.py @@ -28,7 +28,7 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper def list( - self, collection_id: str, item_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, sku_collection_id: str, sku_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> InventoryItem: """ List the current inventory levels for a particular SKU item. @@ -37,11 +37,11 @@ def list( Parameters ---------- - collection_id : str - Unique identifier for a Collection + sku_collection_id : str + Unique identifier for a SKU collection. Use the List Collections API to find this ID. - item_id : str - Unique identifier for an Item + sku_id : str + Unique identifier for a SKU request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -59,12 +59,13 @@ def list( access_token="YOUR_ACCESS_TOKEN", ) client.inventory.list( - collection_id="580e63fc8c9a982ac9b8b745", - item_id="580e64008c9a982ac9b8b754", + sku_collection_id="6377a7c4b7a79608c34a46f7", + sku_id="5e8518516e147040726cc415", ) """ _response = self._client_wrapper.httpx_client.request( - f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/inventory", + f"collections/{jsonable_encoder(sku_collection_id)}/items/{jsonable_encoder(sku_id)}/inventory", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -154,8 +155,8 @@ def list( def update( self, - collection_id: str, - item_id: str, + sku_collection_id: str, + sku_id: str, *, inventory_type: InventoryUpdateRequestInventoryType, update_quantity: typing.Optional[float] = OMIT, @@ -173,11 +174,11 @@ def update( Parameters ---------- - collection_id : str - Unique identifier for a Collection + sku_collection_id : str + Unique identifier for a SKU collection. Use the List Collections API to find this ID. - item_id : str - Unique identifier for an Item + sku_id : str + Unique identifier for a SKU inventory_type : InventoryUpdateRequestInventoryType infinite or finite @@ -204,13 +205,14 @@ def update( access_token="YOUR_ACCESS_TOKEN", ) client.inventory.update( - collection_id="580e63fc8c9a982ac9b8b745", - item_id="580e64008c9a982ac9b8b754", + sku_collection_id="6377a7c4b7a79608c34a46f7", + sku_id="5e8518516e147040726cc415", inventory_type="infinite", ) """ _response = self._client_wrapper.httpx_client.request( - f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/inventory", + f"collections/{jsonable_encoder(sku_collection_id)}/items/{jsonable_encoder(sku_id)}/inventory", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "inventoryType": inventory_type, @@ -313,7 +315,7 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper async def list( - self, collection_id: str, item_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, sku_collection_id: str, sku_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> InventoryItem: """ List the current inventory levels for a particular SKU item. @@ -322,11 +324,11 @@ async def list( Parameters ---------- - collection_id : str - Unique identifier for a Collection + sku_collection_id : str + Unique identifier for a SKU collection. Use the List Collections API to find this ID. - item_id : str - Unique identifier for an Item + sku_id : str + Unique identifier for a SKU request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -349,15 +351,16 @@ async def list( async def main() -> None: await client.inventory.list( - collection_id="580e63fc8c9a982ac9b8b745", - item_id="580e64008c9a982ac9b8b754", + sku_collection_id="6377a7c4b7a79608c34a46f7", + sku_id="5e8518516e147040726cc415", ) asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/inventory", + f"collections/{jsonable_encoder(sku_collection_id)}/items/{jsonable_encoder(sku_id)}/inventory", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -447,8 +450,8 @@ async def main() -> None: async def update( self, - collection_id: str, - item_id: str, + sku_collection_id: str, + sku_id: str, *, inventory_type: InventoryUpdateRequestInventoryType, update_quantity: typing.Optional[float] = OMIT, @@ -466,11 +469,11 @@ async def update( Parameters ---------- - collection_id : str - Unique identifier for a Collection + sku_collection_id : str + Unique identifier for a SKU collection. Use the List Collections API to find this ID. - item_id : str - Unique identifier for an Item + sku_id : str + Unique identifier for a SKU inventory_type : InventoryUpdateRequestInventoryType infinite or finite @@ -502,8 +505,8 @@ async def update( async def main() -> None: await client.inventory.update( - collection_id="580e63fc8c9a982ac9b8b745", - item_id="580e64008c9a982ac9b8b754", + sku_collection_id="6377a7c4b7a79608c34a46f7", + sku_id="5e8518516e147040726cc415", inventory_type="infinite", ) @@ -511,7 +514,8 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/inventory", + f"collections/{jsonable_encoder(sku_collection_id)}/items/{jsonable_encoder(sku_id)}/inventory", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "inventoryType": inventory_type, diff --git a/src/webflow/resources/inventory/types/__init__.py b/src/webflow/resources/inventory/types/__init__.py index e929f4e..4cf7822 100644 --- a/src/webflow/resources/inventory/types/__init__.py +++ b/src/webflow/resources/inventory/types/__init__.py @@ -1,5 +1,6 @@ # This file was auto-generated by Fern from our API Definition. +from .ecomm_inventory_changed_payload import EcommInventoryChangedPayload from .inventory_update_request_inventory_type import InventoryUpdateRequestInventoryType -__all__ = ["InventoryUpdateRequestInventoryType"] +__all__ = ["EcommInventoryChangedPayload", "InventoryUpdateRequestInventoryType"] diff --git a/src/webflow/resources/inventory/types/ecomm_inventory_changed_payload.py b/src/webflow/resources/inventory/types/ecomm_inventory_changed_payload.py new file mode 100644 index 0000000..f4a969e --- /dev/null +++ b/src/webflow/resources/inventory/types/ecomm_inventory_changed_payload.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +from ....core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ....core.serialization import FieldMetadata +from ....types.inventory_item import InventoryItem +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class EcommInventoryChangedPayload(UniversalBaseModel): + trigger_type: typing_extensions.Annotated[ + typing.Optional[typing.Literal["ecomm_inventory_changed"]], FieldMetadata(alias="triggerType") + ] = None + payload: typing.Optional[InventoryItem] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/orders/client.py b/src/webflow/resources/orders/client.py index 4aa4b77..b4f39a2 100644 --- a/src/webflow/resources/orders/client.py +++ b/src/webflow/resources/orders/client.py @@ -34,8 +34,8 @@ def list( site_id: str, *, status: typing.Optional[OrdersListRequestStatus] = None, - offset: typing.Optional[float] = None, - limit: typing.Optional[float] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> OrderList: """ @@ -51,10 +51,10 @@ def list( status : typing.Optional[OrdersListRequestStatus] Filter the orders by status - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records - limit : typing.Optional[float] + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) request_options : typing.Optional[RequestOptions] @@ -74,10 +74,14 @@ def list( ) client.orders.list( site_id="580e63e98c9a982ac9b8b741", + status="pending", + offset=1, + limit=1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "status": status, @@ -207,6 +211,7 @@ def get(self, site_id: str, order_id: str, *, request_options: typing.Optional[R """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -354,6 +359,7 @@ def update( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "comment": comment, @@ -497,6 +503,7 @@ def update_fulfill( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}/fulfill", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "sendOrderFulfilledEmail": send_order_fulfilled_email, @@ -629,6 +636,7 @@ def update_unfulfill( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}/unfulfill", + base_url=self._client_wrapper.get_environment().base, method="POST", request_options=request_options, ) @@ -763,6 +771,7 @@ def refund( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}/refund", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "reason": reason, @@ -867,8 +876,8 @@ async def list( site_id: str, *, status: typing.Optional[OrdersListRequestStatus] = None, - offset: typing.Optional[float] = None, - limit: typing.Optional[float] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> OrderList: """ @@ -884,10 +893,10 @@ async def list( status : typing.Optional[OrdersListRequestStatus] Filter the orders by status - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records - limit : typing.Optional[float] + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) request_options : typing.Optional[RequestOptions] @@ -912,6 +921,9 @@ async def list( async def main() -> None: await client.orders.list( site_id="580e63e98c9a982ac9b8b741", + status="pending", + offset=1, + limit=1, ) @@ -919,6 +931,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "status": status, @@ -1058,6 +1071,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -1213,6 +1227,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "comment": comment, @@ -1364,6 +1379,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}/fulfill", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "sendOrderFulfilledEmail": send_order_fulfilled_email, @@ -1504,6 +1520,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}/unfulfill", + base_url=self._client_wrapper.get_environment().base, method="POST", request_options=request_options, ) @@ -1646,6 +1663,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}/refund", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "reason": reason, diff --git a/src/webflow/resources/pages/__init__.py b/src/webflow/resources/pages/__init__.py index 0fed8e6..898d3de 100644 --- a/src/webflow/resources/pages/__init__.py +++ b/src/webflow/resources/pages/__init__.py @@ -1,6 +1,12 @@ # This file was auto-generated by Fern from our API Definition. -from .types import PageDomWriteNodesItem, UpdateStaticContentResponse +from .types import PageDomWriteNodesItem, PageMetadataWriteOpenGraph, PageMetadataWriteSeo, UpdateStaticContentResponse from .resources import scripts -__all__ = ["PageDomWriteNodesItem", "UpdateStaticContentResponse", "scripts"] +__all__ = [ + "PageDomWriteNodesItem", + "PageMetadataWriteOpenGraph", + "PageMetadataWriteSeo", + "UpdateStaticContentResponse", + "scripts", +] diff --git a/src/webflow/resources/pages/client.py b/src/webflow/resources/pages/client.py index 851f4e7..fb5fe60 100644 --- a/src/webflow/resources/pages/client.py +++ b/src/webflow/resources/pages/client.py @@ -16,9 +16,8 @@ from json.decoder import JSONDecodeError from ...core.api_error import ApiError from ...types.page import Page -import datetime as dt -from ...types.page_seo import PageSeo -from ...types.page_open_graph import PageOpenGraph +from .types.page_metadata_write_seo import PageMetadataWriteSeo +from .types.page_metadata_write_open_graph import PageMetadataWriteOpenGraph from ...core.serialization import convert_and_respect_annotation_metadata from ...types.dom import Dom from ...errors.forbidden_error import ForbiddenError @@ -41,8 +40,8 @@ def list( site_id: str, *, locale_id: typing.Optional[str] = None, - limit: typing.Optional[float] = None, - offset: typing.Optional[float] = None, + limit: typing.Optional[int] = None, + offset: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> PageList: """ @@ -56,12 +55,14 @@ def list( Unique identifier for a Site locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. - limit : typing.Optional[float] + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records request_options : typing.Optional[RequestOptions] @@ -82,10 +83,13 @@ def list( client.pages.list( site_id="580e63e98c9a982ac9b8b741", locale_id="65427cf400e02b306eaa04a0", + limit=1, + offset=1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/pages", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, @@ -176,7 +180,9 @@ def get_metadata( Unique identifier for a Page locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -200,6 +206,7 @@ def get_metadata( """ _response = self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, @@ -274,24 +281,11 @@ def update_page_settings( self, page_id: str, *, - id: str, locale_id: typing.Optional[str] = None, - site_id: typing.Optional[str] = OMIT, title: typing.Optional[str] = OMIT, slug: typing.Optional[str] = OMIT, - parent_id: typing.Optional[str] = OMIT, - collection_id: typing.Optional[str] = OMIT, - created_on: typing.Optional[dt.datetime] = OMIT, - last_updated: typing.Optional[dt.datetime] = OMIT, - archived: typing.Optional[bool] = OMIT, - draft: typing.Optional[bool] = OMIT, - can_branch: typing.Optional[bool] = OMIT, - is_branch: typing.Optional[bool] = OMIT, - is_members_only: typing.Optional[bool] = OMIT, - seo: typing.Optional[PageSeo] = OMIT, - open_graph: typing.Optional[PageOpenGraph] = OMIT, - page_locale_id: typing.Optional[str] = OMIT, - published_path: typing.Optional[str] = OMIT, + seo: typing.Optional[PageMetadataWriteSeo] = OMIT, + open_graph: typing.Optional[PageMetadataWriteOpenGraph] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Page: """ @@ -304,60 +298,26 @@ def update_page_settings( page_id : str Unique identifier for a Page - id : str - Unique identifier for the Page - locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. - site_id : typing.Optional[str] - Unique identifier for the Site + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) title : typing.Optional[str] - Title of the Page + Title for the page slug : typing.Optional[str] - slug of the Page (derived from title) - - parent_id : typing.Optional[str] - Identifier of the parent folder - - collection_id : typing.Optional[str] - Unique identifier for a linked Collection, value will be null if the Page is not part of a Collection. - - created_on : typing.Optional[dt.datetime] - The date the Page was created - - last_updated : typing.Optional[dt.datetime] - The date the Page was most recently updated - - archived : typing.Optional[bool] - Whether the Page has been archived + Slug for the page. - draft : typing.Optional[bool] - Whether the Page is a draft - can_branch : typing.Optional[bool] - Indicates whether the Page supports [Page Branching](https://university.webflow.com/lesson/page-branching) + **Note:** Updating slugs in secondary locales is only supported in Advanced and Enterprise localization add-on plans. - is_branch : typing.Optional[bool] - Indicates whether the Page is a Branch of another Page [Page Branching](https://university.webflow.com/lesson/page-branching) - - is_members_only : typing.Optional[bool] - Indicates whether the Page is restricted by [Memberships Controls](https://university.webflow.com/lesson/webflow-memberships-overview#how-to-manage-page-restrictions) - - seo : typing.Optional[PageSeo] + seo : typing.Optional[PageMetadataWriteSeo] SEO-related fields for the Page - open_graph : typing.Optional[PageOpenGraph] + open_graph : typing.Optional[PageMetadataWriteOpenGraph] Open Graph fields for the Page - page_locale_id : typing.Optional[str] - Unique ID of the page locale - - published_path : typing.Optional[str] - Relative path of the published page URL - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -368,9 +328,11 @@ def update_page_settings( Examples -------- - import datetime - - from webflow import PageOpenGraph, PageSeo, Webflow + from webflow import Webflow + from webflow.resources.pages import ( + PageMetadataWriteOpenGraph, + PageMetadataWriteSeo, + ) client = Webflow( access_token="YOUR_ACCESS_TOKEN", @@ -378,60 +340,39 @@ def update_page_settings( client.pages.update_page_settings( page_id="63c720f9347c2139b248e552", locale_id="65427cf400e02b306eaa04a0", - id="6596da6045e56dee495bcbba", - site_id="6258612d1ee792848f805dcf", title="Guide to the Galaxy", slug="guide-to-the-galaxy", - created_on=datetime.datetime.fromisoformat( - "2024-03-11 10:42:00+00:00", - ), - last_updated=datetime.datetime.fromisoformat( - "2024-03-11 10:42:42+00:00", - ), - archived=False, - draft=False, - can_branch=True, - is_branch=False, - seo=PageSeo( + seo=PageMetadataWriteSeo( title="The Ultimate Hitchhiker's Guide to the Galaxy", description="Everything you need to know about the galaxy, from avoiding Vogon poetry to the importance of towels.", ), - open_graph=PageOpenGraph( + open_graph=PageMetadataWriteOpenGraph( title="Explore the Cosmos with The Ultimate Guide", title_copied=False, description="Dive deep into the mysteries of the universe with your guide to everything galactic.", description_copied=False, ), - page_locale_id="653fd9af6a07fc9cfd7a5e57", - published_path="/en-us/guide-to-the-galaxy", ) """ _response = self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}", + base_url=self._client_wrapper.get_environment().base, method="PUT", params={ "localeId": locale_id, }, json={ - "id": id, - "siteId": site_id, "title": title, "slug": slug, - "parentId": parent_id, - "collectionId": collection_id, - "createdOn": created_on, - "lastUpdated": last_updated, - "archived": archived, - "draft": draft, - "canBranch": can_branch, - "isBranch": is_branch, - "isMembersOnly": is_members_only, - "seo": convert_and_respect_annotation_metadata(object_=seo, annotation=PageSeo, direction="write"), + "seo": convert_and_respect_annotation_metadata( + object_=seo, annotation=PageMetadataWriteSeo, direction="write" + ), "openGraph": convert_and_respect_annotation_metadata( - object_=open_graph, annotation=PageOpenGraph, direction="write" + object_=open_graph, annotation=PageMetadataWriteOpenGraph, direction="write" ), - "localeId": locale_id, - "publishedPath": published_path, + }, + headers={ + "content-type": "application/json", }, request_options=request_options, omit=OMIT, @@ -505,15 +446,14 @@ def get_content( page_id: str, *, locale_id: typing.Optional[str] = None, - limit: typing.Optional[float] = None, - offset: typing.Optional[float] = None, + limit: typing.Optional[int] = None, + offset: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Dom: """ - Get static content from a static page. This includes text nodes, image nodes and component instances. - To retrieve the contents of components in the page use the [get component content](/data/reference/pages-and-components/components/get-content) endpoint. + Get text and component instance content from a static page. - If you do not provide a Locale ID in your request, the response will return any content that can be localized from the Primary locale. + Localization Required scope | `pages:read` @@ -523,12 +463,14 @@ def get_content( Unique identifier for a Page locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. - limit : typing.Optional[float] + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records request_options : typing.Optional[RequestOptions] @@ -549,10 +491,13 @@ def get_content( client.pages.get_content( page_id="63c720f9347c2139b248e552", locale_id="65427cf400e02b306eaa04a0", + limit=1, + offset=1, ) """ _response = self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/dom", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, @@ -647,8 +592,9 @@ def update_static_content( This endpoint updates content on a static page in **secondary locales**. It supports updating up to 1000 nodes in a single request. Before making updates: - 1. Use the [get page content](/data/reference/pages-and-components/pages/get-content) endpoint to identify available content nodes and their types - 2. If the page has component instances, retrieve the component's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint + 1. Use the [get page content](/data/reference/pages-and-components/pages/get-content) endpoint to identify available content nodes and their types. + 2. If the page has component instances, retrieve the component's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint. + 3. DOM elements may include a `data-w-id` attribute. This attribute is used by Webflow to maintain custom attributes and links across locales. Always include the original `data-w-id` value in your update requests to ensure consistent behavior across all locales. This endpoint is specifically for localized pages. Ensure that the specified `localeId` is a valid **secondary locale** for the site otherwise the request will fail. @@ -680,6 +626,10 @@ def update_static_content( from webflow import ( ComponentInstanceNodePropertyOverridesWrite, ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem, + Select, + SelectNodeWriteChoicesItem, + SubmitButtonNodeWrite, + TextInputNodeWrite, TextNodeWrite, Webflow, ) @@ -699,6 +649,28 @@ def update_static_content( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad627", text="

Don't Panic!

Always know where your towel is.

", ), + Select( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad635", + choices=[ + SelectNodeWriteChoicesItem( + value="choice-1", + text="First choice", + ), + SelectNodeWriteChoicesItem( + value="choice-2", + text="Second choice", + ), + ], + ), + TextInputNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad642", + placeholder="Enter something here...", + ), + SubmitButtonNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad671", + value="Submit", + waiting_text="Submitting...", + ), ComponentInstanceNodePropertyOverridesWrite( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad629", property_overrides=[ @@ -717,6 +689,7 @@ def update_static_content( """ _response = self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/dom", + base_url=self._client_wrapper.get_environment().base, method="POST", params={ "localeId": locale_id, @@ -817,8 +790,8 @@ async def list( site_id: str, *, locale_id: typing.Optional[str] = None, - limit: typing.Optional[float] = None, - offset: typing.Optional[float] = None, + limit: typing.Optional[int] = None, + offset: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> PageList: """ @@ -832,12 +805,14 @@ async def list( Unique identifier for a Site locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. - limit : typing.Optional[float] + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records request_options : typing.Optional[RequestOptions] @@ -863,6 +838,8 @@ async def main() -> None: await client.pages.list( site_id="580e63e98c9a982ac9b8b741", locale_id="65427cf400e02b306eaa04a0", + limit=1, + offset=1, ) @@ -870,6 +847,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/pages", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, @@ -960,7 +938,9 @@ async def get_metadata( Unique identifier for a Page locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -992,6 +972,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, @@ -1066,24 +1047,11 @@ async def update_page_settings( self, page_id: str, *, - id: str, locale_id: typing.Optional[str] = None, - site_id: typing.Optional[str] = OMIT, title: typing.Optional[str] = OMIT, slug: typing.Optional[str] = OMIT, - parent_id: typing.Optional[str] = OMIT, - collection_id: typing.Optional[str] = OMIT, - created_on: typing.Optional[dt.datetime] = OMIT, - last_updated: typing.Optional[dt.datetime] = OMIT, - archived: typing.Optional[bool] = OMIT, - draft: typing.Optional[bool] = OMIT, - can_branch: typing.Optional[bool] = OMIT, - is_branch: typing.Optional[bool] = OMIT, - is_members_only: typing.Optional[bool] = OMIT, - seo: typing.Optional[PageSeo] = OMIT, - open_graph: typing.Optional[PageOpenGraph] = OMIT, - page_locale_id: typing.Optional[str] = OMIT, - published_path: typing.Optional[str] = OMIT, + seo: typing.Optional[PageMetadataWriteSeo] = OMIT, + open_graph: typing.Optional[PageMetadataWriteOpenGraph] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Page: """ @@ -1096,60 +1064,26 @@ async def update_page_settings( page_id : str Unique identifier for a Page - id : str - Unique identifier for the Page - locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. - site_id : typing.Optional[str] - Unique identifier for the Site + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) title : typing.Optional[str] - Title of the Page + Title for the page slug : typing.Optional[str] - slug of the Page (derived from title) - - parent_id : typing.Optional[str] - Identifier of the parent folder - - collection_id : typing.Optional[str] - Unique identifier for a linked Collection, value will be null if the Page is not part of a Collection. - - created_on : typing.Optional[dt.datetime] - The date the Page was created - - last_updated : typing.Optional[dt.datetime] - The date the Page was most recently updated + Slug for the page. - archived : typing.Optional[bool] - Whether the Page has been archived - draft : typing.Optional[bool] - Whether the Page is a draft + **Note:** Updating slugs in secondary locales is only supported in Advanced and Enterprise localization add-on plans. - can_branch : typing.Optional[bool] - Indicates whether the Page supports [Page Branching](https://university.webflow.com/lesson/page-branching) - - is_branch : typing.Optional[bool] - Indicates whether the Page is a Branch of another Page [Page Branching](https://university.webflow.com/lesson/page-branching) - - is_members_only : typing.Optional[bool] - Indicates whether the Page is restricted by [Memberships Controls](https://university.webflow.com/lesson/webflow-memberships-overview#how-to-manage-page-restrictions) - - seo : typing.Optional[PageSeo] + seo : typing.Optional[PageMetadataWriteSeo] SEO-related fields for the Page - open_graph : typing.Optional[PageOpenGraph] + open_graph : typing.Optional[PageMetadataWriteOpenGraph] Open Graph fields for the Page - page_locale_id : typing.Optional[str] - Unique ID of the page locale - - published_path : typing.Optional[str] - Relative path of the published page URL - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1161,9 +1095,12 @@ async def update_page_settings( Examples -------- import asyncio - import datetime - from webflow import AsyncWebflow, PageOpenGraph, PageSeo + from webflow import AsyncWebflow + from webflow.resources.pages import ( + PageMetadataWriteOpenGraph, + PageMetadataWriteSeo, + ) client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -1174,32 +1111,18 @@ async def main() -> None: await client.pages.update_page_settings( page_id="63c720f9347c2139b248e552", locale_id="65427cf400e02b306eaa04a0", - id="6596da6045e56dee495bcbba", - site_id="6258612d1ee792848f805dcf", title="Guide to the Galaxy", slug="guide-to-the-galaxy", - created_on=datetime.datetime.fromisoformat( - "2024-03-11 10:42:00+00:00", - ), - last_updated=datetime.datetime.fromisoformat( - "2024-03-11 10:42:42+00:00", - ), - archived=False, - draft=False, - can_branch=True, - is_branch=False, - seo=PageSeo( + seo=PageMetadataWriteSeo( title="The Ultimate Hitchhiker's Guide to the Galaxy", description="Everything you need to know about the galaxy, from avoiding Vogon poetry to the importance of towels.", ), - open_graph=PageOpenGraph( + open_graph=PageMetadataWriteOpenGraph( title="Explore the Cosmos with The Ultimate Guide", title_copied=False, description="Dive deep into the mysteries of the universe with your guide to everything galactic.", description_copied=False, ), - page_locale_id="653fd9af6a07fc9cfd7a5e57", - published_path="/en-us/guide-to-the-galaxy", ) @@ -1207,30 +1130,23 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}", + base_url=self._client_wrapper.get_environment().base, method="PUT", params={ "localeId": locale_id, }, json={ - "id": id, - "siteId": site_id, "title": title, "slug": slug, - "parentId": parent_id, - "collectionId": collection_id, - "createdOn": created_on, - "lastUpdated": last_updated, - "archived": archived, - "draft": draft, - "canBranch": can_branch, - "isBranch": is_branch, - "isMembersOnly": is_members_only, - "seo": convert_and_respect_annotation_metadata(object_=seo, annotation=PageSeo, direction="write"), + "seo": convert_and_respect_annotation_metadata( + object_=seo, annotation=PageMetadataWriteSeo, direction="write" + ), "openGraph": convert_and_respect_annotation_metadata( - object_=open_graph, annotation=PageOpenGraph, direction="write" + object_=open_graph, annotation=PageMetadataWriteOpenGraph, direction="write" ), - "localeId": locale_id, - "publishedPath": published_path, + }, + headers={ + "content-type": "application/json", }, request_options=request_options, omit=OMIT, @@ -1304,15 +1220,14 @@ async def get_content( page_id: str, *, locale_id: typing.Optional[str] = None, - limit: typing.Optional[float] = None, - offset: typing.Optional[float] = None, + limit: typing.Optional[int] = None, + offset: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Dom: """ - Get static content from a static page. This includes text nodes, image nodes and component instances. - To retrieve the contents of components in the page use the [get component content](/data/reference/pages-and-components/components/get-content) endpoint. + Get text and component instance content from a static page. - If you do not provide a Locale ID in your request, the response will return any content that can be localized from the Primary locale. + Localization Required scope | `pages:read` @@ -1322,12 +1237,14 @@ async def get_content( Unique identifier for a Page locale_id : typing.Optional[str] - Unique identifier for a specific locale. Applicable, when using localization. + Unique identifier for a specific Locale. - limit : typing.Optional[float] + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records request_options : typing.Optional[RequestOptions] @@ -1353,6 +1270,8 @@ async def main() -> None: await client.pages.get_content( page_id="63c720f9347c2139b248e552", locale_id="65427cf400e02b306eaa04a0", + limit=1, + offset=1, ) @@ -1360,6 +1279,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/dom", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "localeId": locale_id, @@ -1454,8 +1374,9 @@ async def update_static_content( This endpoint updates content on a static page in **secondary locales**. It supports updating up to 1000 nodes in a single request. Before making updates: - 1. Use the [get page content](/data/reference/pages-and-components/pages/get-content) endpoint to identify available content nodes and their types - 2. If the page has component instances, retrieve the component's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint + 1. Use the [get page content](/data/reference/pages-and-components/pages/get-content) endpoint to identify available content nodes and their types. + 2. If the page has component instances, retrieve the component's properties that you'll override using the [get component properties](/data/reference/pages-and-components/components/get-properties) endpoint. + 3. DOM elements may include a `data-w-id` attribute. This attribute is used by Webflow to maintain custom attributes and links across locales. Always include the original `data-w-id` value in your update requests to ensure consistent behavior across all locales. This endpoint is specifically for localized pages. Ensure that the specified `localeId` is a valid **secondary locale** for the site otherwise the request will fail. @@ -1490,6 +1411,10 @@ async def update_static_content( AsyncWebflow, ComponentInstanceNodePropertyOverridesWrite, ComponentInstanceNodePropertyOverridesWritePropertyOverridesItem, + Select, + SelectNodeWriteChoicesItem, + SubmitButtonNodeWrite, + TextInputNodeWrite, TextNodeWrite, ) @@ -1511,6 +1436,28 @@ async def main() -> None: node_id="a245c12d-995b-55ee-5ec7-aa36a6cad627", text="

Don't Panic!

Always know where your towel is.

", ), + Select( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad635", + choices=[ + SelectNodeWriteChoicesItem( + value="choice-1", + text="First choice", + ), + SelectNodeWriteChoicesItem( + value="choice-2", + text="Second choice", + ), + ], + ), + TextInputNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad642", + placeholder="Enter something here...", + ), + SubmitButtonNodeWrite( + node_id="a245c12d-995b-55ee-5ec7-aa36a6cad671", + value="Submit", + waiting_text="Submitting...", + ), ComponentInstanceNodePropertyOverridesWrite( node_id="a245c12d-995b-55ee-5ec7-aa36a6cad629", property_overrides=[ @@ -1532,6 +1479,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/dom", + base_url=self._client_wrapper.get_environment().base, method="POST", params={ "localeId": locale_id, diff --git a/src/webflow/resources/pages/resources/scripts/client.py b/src/webflow/resources/pages/resources/scripts/client.py index 56bd39a..cd1086f 100644 --- a/src/webflow/resources/pages/resources/scripts/client.py +++ b/src/webflow/resources/pages/resources/scripts/client.py @@ -31,13 +31,7 @@ def get_custom_code( self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> ScriptApplyList: """ - Get all registered scripts that have been applied to a specific Page. - - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + Get all scripts applied to a page. Required scope | `custom_code:read` @@ -67,6 +61,7 @@ def get_custom_code( """ _response = self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -144,15 +139,11 @@ def upsert_custom_code( request_options: typing.Optional[RequestOptions] = None, ) -> ScriptApplyList: """ - Add a registered script to a Page. - - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - - A site can have a maximum of 800 registered scripts. + Apply registered scripts to a page. If you have multiple scripts your App needs to apply or maintain on a page, ensure they are always included in the request body for this endpoint. To remove individual scripts, simply call this endpoint without the script in the request body. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a page, the script must first be registered to a Site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` @@ -204,6 +195,7 @@ def upsert_custom_code( """ _response = self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="PUT", json={ "scripts": convert_and_respect_annotation_metadata( @@ -291,13 +283,11 @@ def upsert_custom_code( def delete_custom_code(self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: """ - Delete the custom code block that an app has created for a page + Remove all scripts from a page applied by the App. This endpoint will not remove scripts from the site's registered scripts. - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. + To remove individual scripts applied by the App, use the [Add/Update Custom Code](/data/reference/custom-code/custom-code-pages/upsert-custom-code) endpoint. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + Access to this endpoint requires a bearer token obtained from an [OAuth Code Grant Flow](/data/reference/oauth-app). Required scope | `custom_code:write` @@ -326,6 +316,7 @@ def delete_custom_code(self, page_id: str, *, request_options: typing.Optional[R """ _response = self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -396,13 +387,7 @@ async def get_custom_code( self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> ScriptApplyList: """ - Get all registered scripts that have been applied to a specific Page. - - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + Get all scripts applied to a page. Required scope | `custom_code:read` @@ -440,6 +425,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -517,15 +503,11 @@ async def upsert_custom_code( request_options: typing.Optional[RequestOptions] = None, ) -> ScriptApplyList: """ - Add a registered script to a Page. - - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - - A site can have a maximum of 800 registered scripts. + Apply registered scripts to a page. If you have multiple scripts your App needs to apply or maintain on a page, ensure they are always included in the request body for this endpoint. To remove individual scripts, simply call this endpoint without the script in the request body. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a page, the script must first be registered to a Site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` @@ -585,6 +567,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="PUT", json={ "scripts": convert_and_respect_annotation_metadata( @@ -674,13 +657,11 @@ async def delete_custom_code( self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> None: """ - Delete the custom code block that an app has created for a page + Remove all scripts from a page applied by the App. This endpoint will not remove scripts from the site's registered scripts. - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. + To remove individual scripts applied by the App, use the [Add/Update Custom Code](/data/reference/custom-code/custom-code-pages/upsert-custom-code) endpoint. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + Access to this endpoint requires a bearer token obtained from an [OAuth Code Grant Flow](/data/reference/oauth-app). Required scope | `custom_code:write` @@ -717,6 +698,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"pages/{jsonable_encoder(page_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) diff --git a/src/webflow/resources/pages/types/__init__.py b/src/webflow/resources/pages/types/__init__.py index 08c0325..6e07bcf 100644 --- a/src/webflow/resources/pages/types/__init__.py +++ b/src/webflow/resources/pages/types/__init__.py @@ -1,6 +1,8 @@ # This file was auto-generated by Fern from our API Definition. from .page_dom_write_nodes_item import PageDomWriteNodesItem +from .page_metadata_write_open_graph import PageMetadataWriteOpenGraph +from .page_metadata_write_seo import PageMetadataWriteSeo from .update_static_content_response import UpdateStaticContentResponse -__all__ = ["PageDomWriteNodesItem", "UpdateStaticContentResponse"] +__all__ = ["PageDomWriteNodesItem", "PageMetadataWriteOpenGraph", "PageMetadataWriteSeo", "UpdateStaticContentResponse"] diff --git a/src/webflow/resources/pages/types/page_dom_write_nodes_item.py b/src/webflow/resources/pages/types/page_dom_write_nodes_item.py index 05d1f3f..7c616d9 100644 --- a/src/webflow/resources/pages/types/page_dom_write_nodes_item.py +++ b/src/webflow/resources/pages/types/page_dom_write_nodes_item.py @@ -3,5 +3,16 @@ import typing from ....types.text_node_write import TextNodeWrite from ....types.component_instance_node_property_overrides_write import ComponentInstanceNodePropertyOverridesWrite +from ....types.select import Select +from ....types.text_input_node_write import TextInputNodeWrite +from ....types.submit_button_node_write import SubmitButtonNodeWrite +from ....types.search_button_node_write import SearchButtonNodeWrite -PageDomWriteNodesItem = typing.Union[TextNodeWrite, ComponentInstanceNodePropertyOverridesWrite] +PageDomWriteNodesItem = typing.Union[ + TextNodeWrite, + ComponentInstanceNodePropertyOverridesWrite, + Select, + TextInputNodeWrite, + SubmitButtonNodeWrite, + SearchButtonNodeWrite, +] diff --git a/src/webflow/resources/pages/types/page_metadata_write_open_graph.py b/src/webflow/resources/pages/types/page_metadata_write_open_graph.py new file mode 100644 index 0000000..7b6a099 --- /dev/null +++ b/src/webflow/resources/pages/types/page_metadata_write_open_graph.py @@ -0,0 +1,47 @@ +# This file was auto-generated by Fern from our API Definition. + +from ....core.pydantic_utilities import UniversalBaseModel +import typing +import pydantic +import typing_extensions +from ....core.serialization import FieldMetadata +from ....core.pydantic_utilities import IS_PYDANTIC_V2 + + +class PageMetadataWriteOpenGraph(UniversalBaseModel): + """ + Open Graph fields for the Page + """ + + title: typing.Optional[str] = pydantic.Field(default=None) + """ + The title supplied to Open Graph annotations + """ + + title_copied: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="titleCopied")] = ( + pydantic.Field(default=None) + ) + """ + Indicates the Open Graph title was copied from the SEO title + """ + + description: typing.Optional[str] = pydantic.Field(default=None) + """ + The description supplied to Open Graph annotations + """ + + description_copied: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="descriptionCopied")] = ( + pydantic.Field(default=None) + ) + """ + Indicates the Open Graph description was copied from the SEO description + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/pages/types/page_metadata_write_seo.py b/src/webflow/resources/pages/types/page_metadata_write_seo.py new file mode 100644 index 0000000..1b339a0 --- /dev/null +++ b/src/webflow/resources/pages/types/page_metadata_write_seo.py @@ -0,0 +1,31 @@ +# This file was auto-generated by Fern from our API Definition. + +from ....core.pydantic_utilities import UniversalBaseModel +import typing +import pydantic +from ....core.pydantic_utilities import IS_PYDANTIC_V2 + + +class PageMetadataWriteSeo(UniversalBaseModel): + """ + SEO-related fields for the Page + """ + + title: typing.Optional[str] = pydantic.Field(default=None) + """ + The Page title shown in search engine results + """ + + description: typing.Optional[str] = pydantic.Field(default=None) + """ + The Page description shown in search engine results + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/products/__init__.py b/src/webflow/resources/products/__init__.py index 9fced2c..adf933b 100644 --- a/src/webflow/resources/products/__init__.py +++ b/src/webflow/resources/products/__init__.py @@ -1,5 +1,5 @@ # This file was auto-generated by Fern from our API Definition. -from .types import ProductsCreateSkuResponse +from .types import ProductSkuCreateProduct, ProductSkuCreateSku, ProductsCreateSkuResponse -__all__ = ["ProductsCreateSkuResponse"] +__all__ = ["ProductSkuCreateProduct", "ProductSkuCreateSku", "ProductsCreateSkuResponse"] diff --git a/src/webflow/resources/products/client.py b/src/webflow/resources/products/client.py index c856fef..5850318 100644 --- a/src/webflow/resources/products/client.py +++ b/src/webflow/resources/products/client.py @@ -16,11 +16,13 @@ from ...errors.internal_server_error import InternalServerError from json.decoder import JSONDecodeError from ...core.api_error import ApiError +from .types.product_sku_create_product import ProductSkuCreateProduct +from .types.product_sku_create_sku import ProductSkuCreateSku from ...types.publish_status import PublishStatus -from ...types.product import Product -from ...types.sku import Sku from ...types.product_and_sk_us import ProductAndSkUs from ...core.serialization import convert_and_respect_annotation_metadata +from ...types.product import Product +from ...types.sku import Sku from .types.products_create_sku_response import ProductsCreateSkuResponse from ...core.client_wrapper import AsyncClientWrapper @@ -36,8 +38,8 @@ def list( self, site_id: str, *, - offset: typing.Optional[float] = None, - limit: typing.Optional[float] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ProductAndSkUsList: """ @@ -53,10 +55,10 @@ def list( site_id : str Unique identifier for a Site - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records - limit : typing.Optional[float] + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) request_options : typing.Optional[RequestOptions] @@ -76,10 +78,13 @@ def list( ) client.products.list( site_id="580e63e98c9a982ac9b8b741", + offset=1, + limit=1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "offset": offset, @@ -175,22 +180,18 @@ def create( self, site_id: str, *, + product: ProductSkuCreateProduct, + sku: ProductSkuCreateSku, publish_status: typing.Optional[PublishStatus] = OMIT, - product: typing.Optional[Product] = OMIT, - sku: typing.Optional[Sku] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> ProductAndSkUs: """ - Create a new product and SKU. - - When you create a product, you will always create a SKU, since a Product Item must have, at minimum, a single SKU. + Create a new ecommerce product and defaultSKU. A product, at minimum, must have a single SKU. - To create a Product with multiple SKUs - for example a T-shirt in sizes small, medium and large: - - Create parameters in `sku-properties`, also known as [product options and variants.](https://help.webflow.com/hc/en-us/articles/33961334531347-Create-product-options-and-variants). - - A single `sku-property` would be `color`. Within the `color` property, list the various colors of T-shirts as an array of `enum` values: `royal-blue`, `crimson-red`, and `forrest-green`. - - Once, you've created a Product and its `sku-properties` with `enum` values, Webflow will create a **default SKU**, which will automatically be a combination of the first `sku-properties` you've created. - - In our example, the default SKU will be a Royal Blue T-Shirt, because our first `enum` of our Color `sku-property` is Royal Blue. - - After you've created your product, you can create additional SKUs using the [Create SKU endpoint.](/data/reference/ecommerce/products/create-sku) + To create a product with multiple SKUs: + - First, create a list of `sku-properties`, also known as [product options](https://help.webflow.com/hc/en-us/articles/33961334531347-Create-product-options-and-variants). For example, a T-shirt product may have a "color" `sku-property`, with a list of enum values: red, yellow, and blue, another `sku-property` may be "size", with a list of enum values: small, medium, and large. + - Once, a product is created with a list of `sku-properties`, Webflow will create a **default SKU**, which is always a combination of the first `enum` values of each `sku-property`. (e.g. Small - Red - T-Shirt) + - After creation, you can create additional SKUs for the product, using the [Create SKUs endpoint.](/data/reference/ecommerce/products/create-sku) Upon creation, the default product type will be `Advanced`, which ensures all Product and SKU fields will be shown to users in the Designer. @@ -201,11 +202,11 @@ def create( site_id : str Unique identifier for a Site - publish_status : typing.Optional[PublishStatus] + product : ProductSkuCreateProduct - product : typing.Optional[Product] + sku : ProductSkuCreateSku - sku : typing.Optional[Sku] + publish_status : typing.Optional[PublishStatus] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -217,24 +218,102 @@ def create( Examples -------- - from webflow import Webflow + from webflow import ( + ProductFieldData, + SkuFieldData, + SkuFieldDataPrice, + SkuPropertyList, + SkuPropertyListEnumItem, + Webflow, + ) + from webflow.resources.products import ( + ProductSkuCreateProduct, + ProductSkuCreateSku, + ) client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.products.create( site_id="580e63e98c9a982ac9b8b741", + publish_status="staging", + product=ProductSkuCreateProduct( + field_data=ProductFieldData( + name="Colorful T-shirt", + slug="colorful-t-shirt", + description="Our best-selling t-shirt available in multiple colors and sizes", + sku_properties=[ + SkuPropertyList( + id="color", + name="Color", + enum=[ + SkuPropertyListEnumItem( + id="red", + name="Red", + slug="red", + ), + SkuPropertyListEnumItem( + id="yellow", + name="Yellow", + slug="yellow", + ), + SkuPropertyListEnumItem( + id="blue", + name="Blue", + slug="blue", + ), + ], + ), + SkuPropertyList( + id="size", + name="Size", + enum=[ + SkuPropertyListEnumItem( + id="small", + name="Small", + slug="small", + ), + SkuPropertyListEnumItem( + id="medium", + name="Medium", + slug="medium", + ), + SkuPropertyListEnumItem( + id="large", + name="Large", + slug="large", + ), + ], + ), + ], + ), + ), + sku=ProductSkuCreateSku( + field_data=SkuFieldData( + name="Colorful T-shirt - Red Small", + slug="colorful-t-shirt-red-small", + price=SkuFieldDataPrice( + value=2499.0, + unit="USD", + currency="USD", + ), + main_image="https://rocketamp-sample-store.myshopify.com/cdn/shop/products/Gildan_2000_Antique_Cherry_Red_Front_1024x1024.jpg?v=1527232987", + ), + ), ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "publishStatus": publish_status, "product": convert_and_respect_annotation_metadata( - object_=product, annotation=Product, direction="write" + object_=product, annotation=ProductSkuCreateProduct, direction="write" + ), + "sku": convert_and_respect_annotation_metadata( + object_=sku, annotation=ProductSkuCreateSku, direction="write" ), - "sku": convert_and_respect_annotation_metadata(object_=sku, annotation=Sku, direction="write"), }, headers={ "content-type": "application/json", @@ -365,6 +444,7 @@ def get( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -505,6 +585,7 @@ def update( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "publishStatus": publish_status, @@ -642,7 +723,9 @@ def create_sku( Examples -------- - from webflow import Sku, Webflow + import datetime + + from webflow import Sku, SkuFieldData, SkuFieldDataPrice, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", @@ -650,11 +733,35 @@ def create_sku( client.products.create_sku( site_id="580e63e98c9a982ac9b8b741", product_id="580e63fc8c9a982ac9b8b745", - skus=[Sku()], + skus=[ + Sku( + id="66072fb71b89448912e2681c", + cms_locale_id="653ad57de882f528b32e810e", + last_published=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + last_updated=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + created_on=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + field_data=SkuFieldData( + name="Colorful T-shirt - Default", + slug="colorful-t-shirt-default", + price=SkuFieldDataPrice( + value=2499.0, + unit="USD", + currency="USD", + ), + ), + ) + ], ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}/skus", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "publishStatus": publish_status, @@ -794,7 +901,9 @@ def update_sku( Examples -------- - from webflow import Sku, Webflow + import datetime + + from webflow import Sku, SkuFieldData, SkuFieldDataPrice, Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", @@ -803,11 +912,33 @@ def update_sku( site_id="580e63e98c9a982ac9b8b741", product_id="580e63fc8c9a982ac9b8b745", sku_id="5e8518516e147040726cc415", - sku=Sku(), + sku=Sku( + id="66072fb71b89448912e2681c", + cms_locale_id="653ad57de882f528b32e810e", + last_published=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + last_updated=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + created_on=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + field_data=SkuFieldData( + name="Colorful T-shirt - Default", + slug="colorful-t-shirt-default", + price=SkuFieldDataPrice( + value=2499.0, + unit="USD", + currency="USD", + ), + ), + ), ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}/skus/{jsonable_encoder(sku_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "publishStatus": publish_status, @@ -912,8 +1043,8 @@ async def list( self, site_id: str, *, - offset: typing.Optional[float] = None, - limit: typing.Optional[float] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ProductAndSkUsList: """ @@ -929,10 +1060,10 @@ async def list( site_id : str Unique identifier for a Site - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records - limit : typing.Optional[float] + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) request_options : typing.Optional[RequestOptions] @@ -957,6 +1088,8 @@ async def list( async def main() -> None: await client.products.list( site_id="580e63e98c9a982ac9b8b741", + offset=1, + limit=1, ) @@ -964,6 +1097,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "offset": offset, @@ -1059,22 +1193,18 @@ async def create( self, site_id: str, *, + product: ProductSkuCreateProduct, + sku: ProductSkuCreateSku, publish_status: typing.Optional[PublishStatus] = OMIT, - product: typing.Optional[Product] = OMIT, - sku: typing.Optional[Sku] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> ProductAndSkUs: """ - Create a new product and SKU. + Create a new ecommerce product and defaultSKU. A product, at minimum, must have a single SKU. - When you create a product, you will always create a SKU, since a Product Item must have, at minimum, a single SKU. - - To create a Product with multiple SKUs - for example a T-shirt in sizes small, medium and large: - - Create parameters in `sku-properties`, also known as [product options and variants.](https://help.webflow.com/hc/en-us/articles/33961334531347-Create-product-options-and-variants). - - A single `sku-property` would be `color`. Within the `color` property, list the various colors of T-shirts as an array of `enum` values: `royal-blue`, `crimson-red`, and `forrest-green`. - - Once, you've created a Product and its `sku-properties` with `enum` values, Webflow will create a **default SKU**, which will automatically be a combination of the first `sku-properties` you've created. - - In our example, the default SKU will be a Royal Blue T-Shirt, because our first `enum` of our Color `sku-property` is Royal Blue. - - After you've created your product, you can create additional SKUs using the [Create SKU endpoint.](/data/reference/ecommerce/products/create-sku) + To create a product with multiple SKUs: + - First, create a list of `sku-properties`, also known as [product options](https://help.webflow.com/hc/en-us/articles/33961334531347-Create-product-options-and-variants). For example, a T-shirt product may have a "color" `sku-property`, with a list of enum values: red, yellow, and blue, another `sku-property` may be "size", with a list of enum values: small, medium, and large. + - Once, a product is created with a list of `sku-properties`, Webflow will create a **default SKU**, which is always a combination of the first `enum` values of each `sku-property`. (e.g. Small - Red - T-Shirt) + - After creation, you can create additional SKUs for the product, using the [Create SKUs endpoint.](/data/reference/ecommerce/products/create-sku) Upon creation, the default product type will be `Advanced`, which ensures all Product and SKU fields will be shown to users in the Designer. @@ -1085,11 +1215,11 @@ async def create( site_id : str Unique identifier for a Site - publish_status : typing.Optional[PublishStatus] + product : ProductSkuCreateProduct - product : typing.Optional[Product] + sku : ProductSkuCreateSku - sku : typing.Optional[Sku] + publish_status : typing.Optional[PublishStatus] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1103,7 +1233,18 @@ async def create( -------- import asyncio - from webflow import AsyncWebflow + from webflow import ( + AsyncWebflow, + ProductFieldData, + SkuFieldData, + SkuFieldDataPrice, + SkuPropertyList, + SkuPropertyListEnumItem, + ) + from webflow.resources.products import ( + ProductSkuCreateProduct, + ProductSkuCreateSku, + ) client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -1113,6 +1254,70 @@ async def create( async def main() -> None: await client.products.create( site_id="580e63e98c9a982ac9b8b741", + publish_status="staging", + product=ProductSkuCreateProduct( + field_data=ProductFieldData( + name="Colorful T-shirt", + slug="colorful-t-shirt", + description="Our best-selling t-shirt available in multiple colors and sizes", + sku_properties=[ + SkuPropertyList( + id="color", + name="Color", + enum=[ + SkuPropertyListEnumItem( + id="red", + name="Red", + slug="red", + ), + SkuPropertyListEnumItem( + id="yellow", + name="Yellow", + slug="yellow", + ), + SkuPropertyListEnumItem( + id="blue", + name="Blue", + slug="blue", + ), + ], + ), + SkuPropertyList( + id="size", + name="Size", + enum=[ + SkuPropertyListEnumItem( + id="small", + name="Small", + slug="small", + ), + SkuPropertyListEnumItem( + id="medium", + name="Medium", + slug="medium", + ), + SkuPropertyListEnumItem( + id="large", + name="Large", + slug="large", + ), + ], + ), + ], + ), + ), + sku=ProductSkuCreateSku( + field_data=SkuFieldData( + name="Colorful T-shirt - Red Small", + slug="colorful-t-shirt-red-small", + price=SkuFieldDataPrice( + value=2499.0, + unit="USD", + currency="USD", + ), + main_image="https://rocketamp-sample-store.myshopify.com/cdn/shop/products/Gildan_2000_Antique_Cherry_Red_Front_1024x1024.jpg?v=1527232987", + ), + ), ) @@ -1120,13 +1325,16 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "publishStatus": publish_status, "product": convert_and_respect_annotation_metadata( - object_=product, annotation=Product, direction="write" + object_=product, annotation=ProductSkuCreateProduct, direction="write" + ), + "sku": convert_and_respect_annotation_metadata( + object_=sku, annotation=ProductSkuCreateSku, direction="write" ), - "sku": convert_and_respect_annotation_metadata(object_=sku, annotation=Sku, direction="write"), }, headers={ "content-type": "application/json", @@ -1265,6 +1473,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -1413,6 +1622,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "publishStatus": publish_status, @@ -1551,8 +1761,9 @@ async def create_sku( Examples -------- import asyncio + import datetime - from webflow import AsyncWebflow, Sku + from webflow import AsyncWebflow, Sku, SkuFieldData, SkuFieldDataPrice client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -1563,7 +1774,30 @@ async def main() -> None: await client.products.create_sku( site_id="580e63e98c9a982ac9b8b741", product_id="580e63fc8c9a982ac9b8b745", - skus=[Sku()], + skus=[ + Sku( + id="66072fb71b89448912e2681c", + cms_locale_id="653ad57de882f528b32e810e", + last_published=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + last_updated=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + created_on=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + field_data=SkuFieldData( + name="Colorful T-shirt - Default", + slug="colorful-t-shirt-default", + price=SkuFieldDataPrice( + value=2499.0, + unit="USD", + currency="USD", + ), + ), + ) + ], ) @@ -1571,6 +1805,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}/skus", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "publishStatus": publish_status, @@ -1711,8 +1946,9 @@ async def update_sku( Examples -------- import asyncio + import datetime - from webflow import AsyncWebflow, Sku + from webflow import AsyncWebflow, Sku, SkuFieldData, SkuFieldDataPrice client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -1724,7 +1960,28 @@ async def main() -> None: site_id="580e63e98c9a982ac9b8b741", product_id="580e63fc8c9a982ac9b8b745", sku_id="5e8518516e147040726cc415", - sku=Sku(), + sku=Sku( + id="66072fb71b89448912e2681c", + cms_locale_id="653ad57de882f528b32e810e", + last_published=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + last_updated=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + created_on=datetime.datetime.fromisoformat( + "2023-03-17 18:47:35+00:00", + ), + field_data=SkuFieldData( + name="Colorful T-shirt - Default", + slug="colorful-t-shirt-default", + price=SkuFieldDataPrice( + value=2499.0, + unit="USD", + currency="USD", + ), + ), + ), ) @@ -1732,6 +1989,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}/skus/{jsonable_encoder(sku_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "publishStatus": publish_status, diff --git a/src/webflow/resources/products/types/__init__.py b/src/webflow/resources/products/types/__init__.py index b078afe..5b6d9b4 100644 --- a/src/webflow/resources/products/types/__init__.py +++ b/src/webflow/resources/products/types/__init__.py @@ -1,5 +1,7 @@ # This file was auto-generated by Fern from our API Definition. +from .product_sku_create_product import ProductSkuCreateProduct +from .product_sku_create_sku import ProductSkuCreateSku from .products_create_sku_response import ProductsCreateSkuResponse -__all__ = ["ProductsCreateSkuResponse"] +__all__ = ["ProductSkuCreateProduct", "ProductSkuCreateSku", "ProductsCreateSkuResponse"] diff --git a/src/webflow/resources/products/types/product_sku_create_product.py b/src/webflow/resources/products/types/product_sku_create_product.py new file mode 100644 index 0000000..750e5f4 --- /dev/null +++ b/src/webflow/resources/products/types/product_sku_create_product.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +from ....core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ....types.product_field_data import ProductFieldData +from ....core.serialization import FieldMetadata +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class ProductSkuCreateProduct(UniversalBaseModel): + field_data: typing_extensions.Annotated[typing.Optional[ProductFieldData], FieldMetadata(alias="fieldData")] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/products/types/product_sku_create_sku.py b/src/webflow/resources/products/types/product_sku_create_sku.py new file mode 100644 index 0000000..2762a9a --- /dev/null +++ b/src/webflow/resources/products/types/product_sku_create_sku.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +from ....core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ....types.sku_field_data import SkuFieldData +from ....core.serialization import FieldMetadata +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +import pydantic + + +class ProductSkuCreateSku(UniversalBaseModel): + field_data: typing_extensions.Annotated[typing.Optional[SkuFieldData], FieldMetadata(alias="fieldData")] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/resources/products/types/products_create_sku_response.py b/src/webflow/resources/products/types/products_create_sku_response.py index e694930..cd68c3d 100644 --- a/src/webflow/resources/products/types/products_create_sku_response.py +++ b/src/webflow/resources/products/types/products_create_sku_response.py @@ -8,7 +8,7 @@ class ProductsCreateSkuResponse(UniversalBaseModel): - skus: typing.Optional[typing.List[Sku]] = None + skus: typing.List[Sku] if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/webflow/resources/scripts/client.py b/src/webflow/resources/scripts/client.py index e9112fb..80026d9 100644 --- a/src/webflow/resources/scripts/client.py +++ b/src/webflow/resources/scripts/client.py @@ -28,14 +28,11 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> RegisteredScriptList: """ - List of scripts registered to a Site. + Get a list of scripts that have been registered to a site. A site can have a maximum of 800 registered scripts. - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - Additionally, Scripts can be remotely hosted, or registered as inline snippets. - - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:read` @@ -65,6 +62,7 @@ def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/registered_scripts", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -144,14 +142,11 @@ def register_hosted( request_options: typing.Optional[RequestOptions] = None, ) -> CustomCodeHostedResponse: """ - Add a script to a Site's Custom Code registry. - - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - Additionally, Scripts can be remotely hosted, or registered as inline snippets. + Register a hosted script to a site. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` @@ -200,6 +195,7 @@ def register_hosted( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/registered_scripts/hosted", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "hostedLocation": hosted_location, @@ -290,13 +286,11 @@ def register_inline( request_options: typing.Optional[RequestOptions] = None, ) -> CustomCodeInlineResponse: """ - Add a script to a Site's Custom Code registry. Inline scripts can be between 1 and 2000 characters. - - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. + Register an inline script to a site. Inline scripts are limited to 2000 characters. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` @@ -344,6 +338,7 @@ def register_inline( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/registered_scripts/inline", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "sourceCode": source_code, @@ -431,14 +426,11 @@ async def list( self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> RegisteredScriptList: """ - List of scripts registered to a Site. + Get a list of scripts that have been registered to a site. A site can have a maximum of 800 registered scripts. - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - Additionally, Scripts can be remotely hosted, or registered as inline snippets. - - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:read` @@ -476,6 +468,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/registered_scripts", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -555,14 +548,11 @@ async def register_hosted( request_options: typing.Optional[RequestOptions] = None, ) -> CustomCodeHostedResponse: """ - Add a script to a Site's Custom Code registry. - - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - Additionally, Scripts can be remotely hosted, or registered as inline snippets. + Register a hosted script to a site. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` @@ -619,6 +609,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/registered_scripts/hosted", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "hostedLocation": hosted_location, @@ -709,13 +700,11 @@ async def register_inline( request_options: typing.Optional[RequestOptions] = None, ) -> CustomCodeInlineResponse: """ - Add a script to a Site's Custom Code registry. Inline scripts can be between 1 and 2000 characters. - - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. + Register an inline script to a site. Inline scripts are limited to 2000 characters. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` @@ -771,6 +760,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/registered_scripts/inline", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "sourceCode": source_code, diff --git a/src/webflow/resources/sites/__init__.py b/src/webflow/resources/sites/__init__.py index 3ec19db..c070ab2 100644 --- a/src/webflow/resources/sites/__init__.py +++ b/src/webflow/resources/sites/__init__.py @@ -1,6 +1,39 @@ # This file was auto-generated by Fern from our API Definition. from .types import SitesPublishResponse -from .resources import activity_logs, plans, redirects, scripts +from .resources import ( + CommentsGetCommentThreadRequestSortBy, + CommentsGetCommentThreadRequestSortOrder, + CommentsListCommentRepliesRequestSortBy, + CommentsListCommentRepliesRequestSortOrder, + CommentsListCommentThreadsRequestSortBy, + CommentsListCommentThreadsRequestSortOrder, + WellKnownFileContentType, + activity_logs, + comments, + forms, + plans, + redirects, + robots_txt, + scripts, + well_known, +) -__all__ = ["SitesPublishResponse", "activity_logs", "plans", "redirects", "scripts"] +__all__ = [ + "CommentsGetCommentThreadRequestSortBy", + "CommentsGetCommentThreadRequestSortOrder", + "CommentsListCommentRepliesRequestSortBy", + "CommentsListCommentRepliesRequestSortOrder", + "CommentsListCommentThreadsRequestSortBy", + "CommentsListCommentThreadsRequestSortOrder", + "SitesPublishResponse", + "WellKnownFileContentType", + "activity_logs", + "comments", + "forms", + "plans", + "redirects", + "robots_txt", + "scripts", + "well_known", +] diff --git a/src/webflow/resources/sites/client.py b/src/webflow/resources/sites/client.py index c2a4468..84b91bd 100644 --- a/src/webflow/resources/sites/client.py +++ b/src/webflow/resources/sites/client.py @@ -4,8 +4,12 @@ from ...core.client_wrapper import SyncClientWrapper from .resources.redirects.client import RedirectsClient from .resources.plans.client import PlansClient +from .resources.robots_txt.client import RobotsTxtClient +from .resources.well_known.client import WellKnownClient from .resources.activity_logs.client import ActivityLogsClient +from .resources.comments.client import CommentsClient from .resources.scripts.client import ScriptsClient +from .resources.forms.client import FormsClient from ...core.request_options import RequestOptions from ...types.site import Site from ...core.jsonable_encoder import jsonable_encoder @@ -25,8 +29,12 @@ from ...core.client_wrapper import AsyncClientWrapper from .resources.redirects.client import AsyncRedirectsClient from .resources.plans.client import AsyncPlansClient +from .resources.robots_txt.client import AsyncRobotsTxtClient +from .resources.well_known.client import AsyncWellKnownClient from .resources.activity_logs.client import AsyncActivityLogsClient +from .resources.comments.client import AsyncCommentsClient from .resources.scripts.client import AsyncScriptsClient +from .resources.forms.client import AsyncFormsClient # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -37,8 +45,12 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper self.redirects = RedirectsClient(client_wrapper=self._client_wrapper) self.plans = PlansClient(client_wrapper=self._client_wrapper) + self.robots_txt = RobotsTxtClient(client_wrapper=self._client_wrapper) + self.well_known = WellKnownClient(client_wrapper=self._client_wrapper) self.activity_logs = ActivityLogsClient(client_wrapper=self._client_wrapper) + self.comments = CommentsClient(client_wrapper=self._client_wrapper) self.scripts = ScriptsClient(client_wrapper=self._client_wrapper) + self.forms = FormsClient(client_wrapper=self._client_wrapper) def create( self, @@ -50,7 +62,9 @@ def create( request_options: typing.Optional[RequestOptions] = None, ) -> Site: """ - Create a site. This endpoint requires an Enterprise workspace. + Create a site. + + This endpoint requires an Enterprise workspace. Required scope | `workspace:write` @@ -90,6 +104,7 @@ def create( """ _response = self._client_wrapper.httpx_client.request( f"workspaces/{jsonable_encoder(workspace_id)}/sites", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "name": name, @@ -203,6 +218,7 @@ def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> Si """ _response = self._client_wrapper.httpx_client.request( "sites", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -282,6 +298,7 @@ def get(self, site_id: str, *, request_options: typing.Optional[RequestOptions] """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -351,7 +368,9 @@ def get(self, site_id: str, *, request_options: typing.Optional[RequestOptions] def delete(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: """ - Delete a site. This endpoint requires an Enterprise workspace. + Delete a site. + + This endpoint requires an Enterprise workspace. Required scope | `sites:write` @@ -380,6 +399,7 @@ def delete(self, site_id: str, *, request_options: typing.Optional[RequestOption """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -460,7 +480,9 @@ def update( request_options: typing.Optional[RequestOptions] = None, ) -> Site: """ - Update a site. This endpoint requires an Enterprise workspace. + Update a site. + + This endpoint requires an Enterprise workspace. Required scope | `sites:write` @@ -496,6 +518,7 @@ def update( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "name": name, @@ -613,6 +636,7 @@ def get_custom_domain(self, site_id: str, *, request_options: typing.Optional[Re """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_domains", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -691,7 +715,9 @@ def publish( """ Publishes a site to one or more more domains. - This endpoint has a limit of one successful publish queue per minute. + To publish to a specific custom domain, use the domain IDs from the [Get Custom Domains](/data/reference/sites/get-custom-domain) endpoint. + + This endpoint has a specific rate limit of one successful publish queue per minute. Required scope | `sites:write` @@ -723,10 +749,13 @@ def publish( ) client.sites.publish( site_id="580e63e98c9a982ac9b8b741", + custom_domains=["660c6449dd97ebc7346ac629", "660c6449dd97ebc7346ac62f"], + publish_to_webflow_subdomain=False, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/publish", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "customDomains": custom_domains, @@ -808,8 +837,12 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper self.redirects = AsyncRedirectsClient(client_wrapper=self._client_wrapper) self.plans = AsyncPlansClient(client_wrapper=self._client_wrapper) + self.robots_txt = AsyncRobotsTxtClient(client_wrapper=self._client_wrapper) + self.well_known = AsyncWellKnownClient(client_wrapper=self._client_wrapper) self.activity_logs = AsyncActivityLogsClient(client_wrapper=self._client_wrapper) + self.comments = AsyncCommentsClient(client_wrapper=self._client_wrapper) self.scripts = AsyncScriptsClient(client_wrapper=self._client_wrapper) + self.forms = AsyncFormsClient(client_wrapper=self._client_wrapper) async def create( self, @@ -821,7 +854,9 @@ async def create( request_options: typing.Optional[RequestOptions] = None, ) -> Site: """ - Create a site. This endpoint requires an Enterprise workspace. + Create a site. + + This endpoint requires an Enterprise workspace. Required scope | `workspace:write` @@ -869,6 +904,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"workspaces/{jsonable_encoder(workspace_id)}/sites", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "name": name, @@ -990,6 +1026,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( "sites", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -1077,6 +1114,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -1146,7 +1184,9 @@ async def main() -> None: async def delete(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: """ - Delete a site. This endpoint requires an Enterprise workspace. + Delete a site. + + This endpoint requires an Enterprise workspace. Required scope | `sites:write` @@ -1183,6 +1223,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -1263,7 +1304,9 @@ async def update( request_options: typing.Optional[RequestOptions] = None, ) -> Site: """ - Update a site. This endpoint requires an Enterprise workspace. + Update a site. + + This endpoint requires an Enterprise workspace. Required scope | `sites:write` @@ -1307,6 +1350,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "name": name, @@ -1434,6 +1478,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_domains", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -1512,7 +1557,9 @@ async def publish( """ Publishes a site to one or more more domains. - This endpoint has a limit of one successful publish queue per minute. + To publish to a specific custom domain, use the domain IDs from the [Get Custom Domains](/data/reference/sites/get-custom-domain) endpoint. + + This endpoint has a specific rate limit of one successful publish queue per minute. Required scope | `sites:write` @@ -1549,6 +1596,8 @@ async def publish( async def main() -> None: await client.sites.publish( site_id="580e63e98c9a982ac9b8b741", + custom_domains=["660c6449dd97ebc7346ac629", "660c6449dd97ebc7346ac62f"], + publish_to_webflow_subdomain=False, ) @@ -1556,6 +1605,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/publish", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "customDomains": custom_domains, diff --git a/src/webflow/resources/sites/resources/__init__.py b/src/webflow/resources/sites/resources/__init__.py index 1197a83..578d8dc 100644 --- a/src/webflow/resources/sites/resources/__init__.py +++ b/src/webflow/resources/sites/resources/__init__.py @@ -1,5 +1,30 @@ # This file was auto-generated by Fern from our API Definition. -from . import activity_logs, plans, redirects, scripts +from . import activity_logs, comments, forms, plans, redirects, robots_txt, scripts, well_known +from .comments import ( + CommentsGetCommentThreadRequestSortBy, + CommentsGetCommentThreadRequestSortOrder, + CommentsListCommentRepliesRequestSortBy, + CommentsListCommentRepliesRequestSortOrder, + CommentsListCommentThreadsRequestSortBy, + CommentsListCommentThreadsRequestSortOrder, +) +from .well_known import WellKnownFileContentType -__all__ = ["activity_logs", "plans", "redirects", "scripts"] +__all__ = [ + "CommentsGetCommentThreadRequestSortBy", + "CommentsGetCommentThreadRequestSortOrder", + "CommentsListCommentRepliesRequestSortBy", + "CommentsListCommentRepliesRequestSortOrder", + "CommentsListCommentThreadsRequestSortBy", + "CommentsListCommentThreadsRequestSortOrder", + "WellKnownFileContentType", + "activity_logs", + "comments", + "forms", + "plans", + "redirects", + "robots_txt", + "scripts", + "well_known", +] diff --git a/src/webflow/resources/sites/resources/activity_logs/client.py b/src/webflow/resources/sites/resources/activity_logs/client.py index cf4e1b3..d36303b 100644 --- a/src/webflow/resources/sites/resources/activity_logs/client.py +++ b/src/webflow/resources/sites/resources/activity_logs/client.py @@ -24,22 +24,26 @@ def list( self, site_id: str, *, - limit: typing.Optional[float] = None, - offset: typing.Optional[float] = None, + limit: typing.Optional[int] = None, + offset: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SiteActivityLogResponse: """ - Retrieve Activity Logs for a specific Site. Requires Site to be on an Enterprise plan.

Required scope | `site_activity:read` + Retrieve Activity Logs for a specific Site. + + This endpoint requires an Enterprise workspace. + + Required scope: `site_activity:read` Parameters ---------- site_id : str Unique identifier for a Site - limit : typing.Optional[float] + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records request_options : typing.Optional[RequestOptions] @@ -59,10 +63,13 @@ def list( ) client.sites.activity_logs.list( site_id="580e63e98c9a982ac9b8b741", + limit=1, + offset=1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/activity_logs", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "limit": limit, @@ -133,22 +140,26 @@ async def list( self, site_id: str, *, - limit: typing.Optional[float] = None, - offset: typing.Optional[float] = None, + limit: typing.Optional[int] = None, + offset: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SiteActivityLogResponse: """ - Retrieve Activity Logs for a specific Site. Requires Site to be on an Enterprise plan.

Required scope | `site_activity:read` + Retrieve Activity Logs for a specific Site. + + This endpoint requires an Enterprise workspace. + + Required scope: `site_activity:read` Parameters ---------- site_id : str Unique identifier for a Site - limit : typing.Optional[float] + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records request_options : typing.Optional[RequestOptions] @@ -173,6 +184,8 @@ async def list( async def main() -> None: await client.sites.activity_logs.list( site_id="580e63e98c9a982ac9b8b741", + limit=1, + offset=1, ) @@ -180,6 +193,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/activity_logs", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "limit": limit, diff --git a/src/webflow/resources/sites/resources/comments/__init__.py b/src/webflow/resources/sites/resources/comments/__init__.py new file mode 100644 index 0000000..1bf96a0 --- /dev/null +++ b/src/webflow/resources/sites/resources/comments/__init__.py @@ -0,0 +1,19 @@ +# This file was auto-generated by Fern from our API Definition. + +from .types import ( + CommentsGetCommentThreadRequestSortBy, + CommentsGetCommentThreadRequestSortOrder, + CommentsListCommentRepliesRequestSortBy, + CommentsListCommentRepliesRequestSortOrder, + CommentsListCommentThreadsRequestSortBy, + CommentsListCommentThreadsRequestSortOrder, +) + +__all__ = [ + "CommentsGetCommentThreadRequestSortBy", + "CommentsGetCommentThreadRequestSortOrder", + "CommentsListCommentRepliesRequestSortBy", + "CommentsListCommentRepliesRequestSortOrder", + "CommentsListCommentThreadsRequestSortBy", + "CommentsListCommentThreadsRequestSortOrder", +] diff --git a/src/webflow/resources/sites/resources/comments/client.py b/src/webflow/resources/sites/resources/comments/client.py new file mode 100644 index 0000000..748e6e5 --- /dev/null +++ b/src/webflow/resources/sites/resources/comments/client.py @@ -0,0 +1,937 @@ +# This file was auto-generated by Fern from our API Definition. + +from .....core.client_wrapper import SyncClientWrapper +import typing +from .types.comments_list_comment_threads_request_sort_by import CommentsListCommentThreadsRequestSortBy +from .types.comments_list_comment_threads_request_sort_order import CommentsListCommentThreadsRequestSortOrder +from .....core.request_options import RequestOptions +from .....types.comment_thread_list import CommentThreadList +from .....core.jsonable_encoder import jsonable_encoder +from .....core.pydantic_utilities import parse_obj_as +from .....errors.bad_request_error import BadRequestError +from .....errors.unauthorized_error import UnauthorizedError +from .....types.error import Error +from .....errors.not_found_error import NotFoundError +from .....errors.too_many_requests_error import TooManyRequestsError +from .....errors.internal_server_error import InternalServerError +from json.decoder import JSONDecodeError +from .....core.api_error import ApiError +from .types.comments_get_comment_thread_request_sort_by import CommentsGetCommentThreadRequestSortBy +from .types.comments_get_comment_thread_request_sort_order import CommentsGetCommentThreadRequestSortOrder +from .....types.comment_thread import CommentThread +from .types.comments_list_comment_replies_request_sort_by import CommentsListCommentRepliesRequestSortBy +from .types.comments_list_comment_replies_request_sort_order import CommentsListCommentRepliesRequestSortOrder +from .....types.comment_reply_list import CommentReplyList +from .....core.client_wrapper import AsyncClientWrapper + + +class CommentsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list_comment_threads( + self, + site_id: str, + *, + locale_id: typing.Optional[str] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + sort_by: typing.Optional[CommentsListCommentThreadsRequestSortBy] = None, + sort_order: typing.Optional[CommentsListCommentThreadsRequestSortOrder] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> CommentThreadList: + """ + List all comment threads for a site. + + + There may be a delay of up to 5 minutes before new comments appear in the system. + + + Required scope | `comments:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + locale_id : typing.Optional[str] + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + offset : typing.Optional[int] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[int] + Maximum number of records to be returned (max limit: 100) + + sort_by : typing.Optional[CommentsListCommentThreadsRequestSortBy] + Sort results by the provided value. Only allowed when sortOrder is provided. + + sort_order : typing.Optional[CommentsListCommentThreadsRequestSortOrder] + Sorts the results by asc or desc + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CommentThreadList + Request was successful + + Examples + -------- + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.comments.list_comment_threads( + site_id="580e63e98c9a982ac9b8b741", + locale_id="65427cf400e02b306eaa04a0", + offset=1, + limit=1, + sort_by="createdOn", + sort_order="asc", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/comments", + base_url=self._client_wrapper.get_environment().base, + method="GET", + params={ + "localeId": locale_id, + "offset": offset, + "limit": limit, + "sortBy": sort_by, + "sortOrder": sort_order, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + CommentThreadList, + parse_obj_as( + type_=CommentThreadList, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def get_comment_thread( + self, + site_id: str, + comment_thread_id: str, + *, + locale_id: typing.Optional[str] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + sort_by: typing.Optional[CommentsGetCommentThreadRequestSortBy] = None, + sort_order: typing.Optional[CommentsGetCommentThreadRequestSortOrder] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> CommentThread: + """ + Get details of a specific comment thread. + + + There may be a delay of up to 5 minutes before new comments appear in the system. + + + Required scope | `comments:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + comment_thread_id : str + Unique identifier for a Comment Thread + + locale_id : typing.Optional[str] + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + offset : typing.Optional[int] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[int] + Maximum number of records to be returned (max limit: 100) + + sort_by : typing.Optional[CommentsGetCommentThreadRequestSortBy] + Sort results by the provided value. Only allowed when sortOrder is provided. + + sort_order : typing.Optional[CommentsGetCommentThreadRequestSortOrder] + Sorts the results by asc or desc + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CommentThread + Request was successful + + Examples + -------- + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.comments.get_comment_thread( + site_id="580e63e98c9a982ac9b8b741", + comment_thread_id="580e63e98c9a982ac9b8b741", + locale_id="65427cf400e02b306eaa04a0", + offset=1, + limit=1, + sort_by="createdOn", + sort_order="asc", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/comments/{jsonable_encoder(comment_thread_id)}", + base_url=self._client_wrapper.get_environment().base, + method="GET", + params={ + "localeId": locale_id, + "offset": offset, + "limit": limit, + "sortBy": sort_by, + "sortOrder": sort_order, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + CommentThread, + parse_obj_as( + type_=CommentThread, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def list_comment_replies( + self, + site_id: str, + comment_thread_id: str, + *, + locale_id: typing.Optional[str] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + sort_by: typing.Optional[CommentsListCommentRepliesRequestSortBy] = None, + sort_order: typing.Optional[CommentsListCommentRepliesRequestSortOrder] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> CommentReplyList: + """ + List all replies to a specific comment thread. + + + There may be a delay of up to 5 minutes before new comments appear in the system. + + + Required scope | `comments:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + comment_thread_id : str + Unique identifier for a Comment Thread + + locale_id : typing.Optional[str] + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + offset : typing.Optional[int] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[int] + Maximum number of records to be returned (max limit: 100) + + sort_by : typing.Optional[CommentsListCommentRepliesRequestSortBy] + Sort results by the provided value. Only allowed when sortOrder is provided. + + sort_order : typing.Optional[CommentsListCommentRepliesRequestSortOrder] + Sorts the results by asc or desc + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CommentReplyList + Request was successful + + Examples + -------- + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.comments.list_comment_replies( + site_id="580e63e98c9a982ac9b8b741", + comment_thread_id="580e63e98c9a982ac9b8b741", + locale_id="65427cf400e02b306eaa04a0", + offset=1, + limit=1, + sort_by="createdOn", + sort_order="asc", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/comments/{jsonable_encoder(comment_thread_id)}/replies", + base_url=self._client_wrapper.get_environment().base, + method="GET", + params={ + "localeId": locale_id, + "offset": offset, + "limit": limit, + "sortBy": sort_by, + "sortOrder": sort_order, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + CommentReplyList, + parse_obj_as( + type_=CommentReplyList, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + +class AsyncCommentsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list_comment_threads( + self, + site_id: str, + *, + locale_id: typing.Optional[str] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + sort_by: typing.Optional[CommentsListCommentThreadsRequestSortBy] = None, + sort_order: typing.Optional[CommentsListCommentThreadsRequestSortOrder] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> CommentThreadList: + """ + List all comment threads for a site. + + + There may be a delay of up to 5 minutes before new comments appear in the system. + + + Required scope | `comments:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + locale_id : typing.Optional[str] + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + offset : typing.Optional[int] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[int] + Maximum number of records to be returned (max limit: 100) + + sort_by : typing.Optional[CommentsListCommentThreadsRequestSortBy] + Sort results by the provided value. Only allowed when sortOrder is provided. + + sort_order : typing.Optional[CommentsListCommentThreadsRequestSortOrder] + Sorts the results by asc or desc + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CommentThreadList + Request was successful + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.comments.list_comment_threads( + site_id="580e63e98c9a982ac9b8b741", + locale_id="65427cf400e02b306eaa04a0", + offset=1, + limit=1, + sort_by="createdOn", + sort_order="asc", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/comments", + base_url=self._client_wrapper.get_environment().base, + method="GET", + params={ + "localeId": locale_id, + "offset": offset, + "limit": limit, + "sortBy": sort_by, + "sortOrder": sort_order, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + CommentThreadList, + parse_obj_as( + type_=CommentThreadList, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def get_comment_thread( + self, + site_id: str, + comment_thread_id: str, + *, + locale_id: typing.Optional[str] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + sort_by: typing.Optional[CommentsGetCommentThreadRequestSortBy] = None, + sort_order: typing.Optional[CommentsGetCommentThreadRequestSortOrder] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> CommentThread: + """ + Get details of a specific comment thread. + + + There may be a delay of up to 5 minutes before new comments appear in the system. + + + Required scope | `comments:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + comment_thread_id : str + Unique identifier for a Comment Thread + + locale_id : typing.Optional[str] + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + offset : typing.Optional[int] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[int] + Maximum number of records to be returned (max limit: 100) + + sort_by : typing.Optional[CommentsGetCommentThreadRequestSortBy] + Sort results by the provided value. Only allowed when sortOrder is provided. + + sort_order : typing.Optional[CommentsGetCommentThreadRequestSortOrder] + Sorts the results by asc or desc + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CommentThread + Request was successful + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.comments.get_comment_thread( + site_id="580e63e98c9a982ac9b8b741", + comment_thread_id="580e63e98c9a982ac9b8b741", + locale_id="65427cf400e02b306eaa04a0", + offset=1, + limit=1, + sort_by="createdOn", + sort_order="asc", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/comments/{jsonable_encoder(comment_thread_id)}", + base_url=self._client_wrapper.get_environment().base, + method="GET", + params={ + "localeId": locale_id, + "offset": offset, + "limit": limit, + "sortBy": sort_by, + "sortOrder": sort_order, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + CommentThread, + parse_obj_as( + type_=CommentThread, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def list_comment_replies( + self, + site_id: str, + comment_thread_id: str, + *, + locale_id: typing.Optional[str] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + sort_by: typing.Optional[CommentsListCommentRepliesRequestSortBy] = None, + sort_order: typing.Optional[CommentsListCommentRepliesRequestSortOrder] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> CommentReplyList: + """ + List all replies to a specific comment thread. + + + There may be a delay of up to 5 minutes before new comments appear in the system. + + + Required scope | `comments:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + comment_thread_id : str + Unique identifier for a Comment Thread + + locale_id : typing.Optional[str] + Unique identifier for a specific Locale. + + [Lear more about localization.](/data/v2.0.0/docs/working-with-localization) + + offset : typing.Optional[int] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[int] + Maximum number of records to be returned (max limit: 100) + + sort_by : typing.Optional[CommentsListCommentRepliesRequestSortBy] + Sort results by the provided value. Only allowed when sortOrder is provided. + + sort_order : typing.Optional[CommentsListCommentRepliesRequestSortOrder] + Sorts the results by asc or desc + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CommentReplyList + Request was successful + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.comments.list_comment_replies( + site_id="580e63e98c9a982ac9b8b741", + comment_thread_id="580e63e98c9a982ac9b8b741", + locale_id="65427cf400e02b306eaa04a0", + offset=1, + limit=1, + sort_by="createdOn", + sort_order="asc", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/comments/{jsonable_encoder(comment_thread_id)}/replies", + base_url=self._client_wrapper.get_environment().base, + method="GET", + params={ + "localeId": locale_id, + "offset": offset, + "limit": limit, + "sortBy": sort_by, + "sortOrder": sort_order, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + CommentReplyList, + parse_obj_as( + type_=CommentReplyList, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) diff --git a/src/webflow/resources/sites/resources/comments/types/__init__.py b/src/webflow/resources/sites/resources/comments/types/__init__.py new file mode 100644 index 0000000..380d194 --- /dev/null +++ b/src/webflow/resources/sites/resources/comments/types/__init__.py @@ -0,0 +1,17 @@ +# This file was auto-generated by Fern from our API Definition. + +from .comments_get_comment_thread_request_sort_by import CommentsGetCommentThreadRequestSortBy +from .comments_get_comment_thread_request_sort_order import CommentsGetCommentThreadRequestSortOrder +from .comments_list_comment_replies_request_sort_by import CommentsListCommentRepliesRequestSortBy +from .comments_list_comment_replies_request_sort_order import CommentsListCommentRepliesRequestSortOrder +from .comments_list_comment_threads_request_sort_by import CommentsListCommentThreadsRequestSortBy +from .comments_list_comment_threads_request_sort_order import CommentsListCommentThreadsRequestSortOrder + +__all__ = [ + "CommentsGetCommentThreadRequestSortBy", + "CommentsGetCommentThreadRequestSortOrder", + "CommentsListCommentRepliesRequestSortBy", + "CommentsListCommentRepliesRequestSortOrder", + "CommentsListCommentThreadsRequestSortBy", + "CommentsListCommentThreadsRequestSortOrder", +] diff --git a/src/webflow/resources/sites/resources/comments/types/comments_get_comment_thread_request_sort_by.py b/src/webflow/resources/sites/resources/comments/types/comments_get_comment_thread_request_sort_by.py new file mode 100644 index 0000000..14daabb --- /dev/null +++ b/src/webflow/resources/sites/resources/comments/types/comments_get_comment_thread_request_sort_by.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CommentsGetCommentThreadRequestSortBy = typing.Union[typing.Literal["createdOn", "lastUpdated"], typing.Any] diff --git a/src/webflow/resources/sites/resources/comments/types/comments_get_comment_thread_request_sort_order.py b/src/webflow/resources/sites/resources/comments/types/comments_get_comment_thread_request_sort_order.py new file mode 100644 index 0000000..3da3ffc --- /dev/null +++ b/src/webflow/resources/sites/resources/comments/types/comments_get_comment_thread_request_sort_order.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CommentsGetCommentThreadRequestSortOrder = typing.Union[typing.Literal["asc", "desc"], typing.Any] diff --git a/src/webflow/resources/sites/resources/comments/types/comments_list_comment_replies_request_sort_by.py b/src/webflow/resources/sites/resources/comments/types/comments_list_comment_replies_request_sort_by.py new file mode 100644 index 0000000..67fcb98 --- /dev/null +++ b/src/webflow/resources/sites/resources/comments/types/comments_list_comment_replies_request_sort_by.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CommentsListCommentRepliesRequestSortBy = typing.Union[typing.Literal["createdOn", "lastUpdated"], typing.Any] diff --git a/src/webflow/resources/sites/resources/comments/types/comments_list_comment_replies_request_sort_order.py b/src/webflow/resources/sites/resources/comments/types/comments_list_comment_replies_request_sort_order.py new file mode 100644 index 0000000..03c42c3 --- /dev/null +++ b/src/webflow/resources/sites/resources/comments/types/comments_list_comment_replies_request_sort_order.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CommentsListCommentRepliesRequestSortOrder = typing.Union[typing.Literal["asc", "desc"], typing.Any] diff --git a/src/webflow/resources/sites/resources/comments/types/comments_list_comment_threads_request_sort_by.py b/src/webflow/resources/sites/resources/comments/types/comments_list_comment_threads_request_sort_by.py new file mode 100644 index 0000000..1d541ce --- /dev/null +++ b/src/webflow/resources/sites/resources/comments/types/comments_list_comment_threads_request_sort_by.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CommentsListCommentThreadsRequestSortBy = typing.Union[typing.Literal["createdOn", "lastUpdated"], typing.Any] diff --git a/src/webflow/resources/sites/resources/comments/types/comments_list_comment_threads_request_sort_order.py b/src/webflow/resources/sites/resources/comments/types/comments_list_comment_threads_request_sort_order.py new file mode 100644 index 0000000..d2c2606 --- /dev/null +++ b/src/webflow/resources/sites/resources/comments/types/comments_list_comment_threads_request_sort_order.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CommentsListCommentThreadsRequestSortOrder = typing.Union[typing.Literal["asc", "desc"], typing.Any] diff --git a/src/webflow/types/user_limit_reached.py b/src/webflow/resources/sites/resources/forms/__init__.py similarity index 51% rename from src/webflow/types/user_limit_reached.py rename to src/webflow/resources/sites/resources/forms/__init__.py index 7f149c2..f3ea265 100644 --- a/src/webflow/types/user_limit_reached.py +++ b/src/webflow/resources/sites/resources/forms/__init__.py @@ -1,5 +1,2 @@ # This file was auto-generated by Fern from our API Definition. -import typing - -UserLimitReached = typing.Optional[typing.Any] diff --git a/src/webflow/resources/users/client.py b/src/webflow/resources/sites/resources/forms/client.py similarity index 74% rename from src/webflow/resources/users/client.py rename to src/webflow/resources/sites/resources/forms/client.py index d690c0f..7b253a9 100644 --- a/src/webflow/resources/users/client.py +++ b/src/webflow/resources/sites/resources/forms/client.py @@ -1,73 +1,74 @@ # This file was auto-generated by Fern from our API Definition. import typing -from ...core.client_wrapper import SyncClientWrapper -from .types.users_list_request_sort import UsersListRequestSort -from ...core.request_options import RequestOptions -from ...types.user_list import UserList -from ...core.jsonable_encoder import jsonable_encoder -from ...core.pydantic_utilities import parse_obj_as -from ...errors.bad_request_error import BadRequestError -from ...errors.unauthorized_error import UnauthorizedError -from ...types.error import Error -from ...errors.forbidden_error import ForbiddenError -from ...errors.not_found_error import NotFoundError -from ...errors.too_many_requests_error import TooManyRequestsError -from ...errors.internal_server_error import InternalServerError +from .....core.client_wrapper import SyncClientWrapper +from .....core.request_options import RequestOptions +from .....types.form_submission_list import FormSubmissionList +from .....core.jsonable_encoder import jsonable_encoder +from .....core.pydantic_utilities import parse_obj_as +from .....errors.bad_request_error import BadRequestError +from .....errors.unauthorized_error import UnauthorizedError +from .....types.error import Error +from .....errors.forbidden_error import ForbiddenError +from .....errors.not_found_error import NotFoundError +from .....errors.too_many_requests_error import TooManyRequestsError +from .....errors.internal_server_error import InternalServerError from json.decoder import JSONDecodeError -from ...core.api_error import ApiError -from ...types.user import User -from .types.users_update_request_data import UsersUpdateRequestData -from ...core.serialization import convert_and_respect_annotation_metadata -from ...errors.conflict_error import ConflictError -from ...core.client_wrapper import AsyncClientWrapper +from .....core.api_error import ApiError +from .....types.form_submission import FormSubmission +from .....errors.conflict_error import ConflictError +from .....core.client_wrapper import AsyncClientWrapper # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) -class UsersClient: +class FormsClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper - def list( + def list_submissions_by_site( self, site_id: str, *, - offset: typing.Optional[float] = None, - limit: typing.Optional[float] = None, - sort: typing.Optional[UsersListRequestSort] = None, + element_id: typing.Optional[str] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> UserList: + ) -> FormSubmissionList: """ - Get a list of users for a site + List all form submissions for a given site with the ability to filter submissions by a centralized `elementId`. - Required scope | `users:read` + Add `elementId` when you want to filter form submissions to a specific form in a site. You can get the `elementId` from the [List forms endpoint](/data/reference/forms/forms/list) (displayed as `formElementId` in the response). + + + When a form is used in a Webflow component definition, each instance of the component will yield a unique form. Adding the `elementId` in this request ensures this API response includes all submissions from that core form, wherever that form is used in instantiated components. + + + Use the [List Form Submissions endpoint](/data/reference/forms/form-submissions/list-submissions) to list form submissions for a given form ID. + + Required scope | `forms:read` Parameters ---------- site_id : str Unique identifier for a Site - offset : typing.Optional[float] + element_id : typing.Optional[str] + Identifier for an element + + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records - limit : typing.Optional[float] + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) - sort : typing.Optional[UsersListRequestSort] - Sort string to use when ordering users - - Example(`CreatedOn`, `Email`, `Status`, `LastLogin`, `UpdatedOn`). - - Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`) - request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - UserList + FormSubmissionList Request was successful Examples @@ -77,26 +78,30 @@ def list( client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) - client.users.list( + client.sites.forms.list_submissions_by_site( site_id="580e63e98c9a982ac9b8b741", + element_id="18259716-3e5a-646a-5f41-5dc4b9405aa0", + offset=1, + limit=1, ) """ _response = self._client_wrapper.httpx_client.request( - f"sites/{jsonable_encoder(site_id)}/users", + f"sites/{jsonable_encoder(site_id)}/form_submissions", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ + "elementId": element_id, "offset": offset, "limit": limit, - "sort": sort, }, request_options=request_options, ) try: if 200 <= _response.status_code < 300: return typing.cast( - UserList, + FormSubmissionList, parse_obj_as( - type_=UserList, # type: ignore + type_=FormSubmissionList, # type: ignore object_=_response.json(), ), ) @@ -165,26 +170,42 @@ def list( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def get(self, site_id: str, user_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> User: + def list_submissions( + self, + site_id: str, + form_id: str, + *, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> FormSubmissionList: """ - Get a User by ID + List form submissions for a given form ID within a specific site. + + Use the [List Form Submissions by Site endpoint](/data/reference/forms/form-submissions/list-submissions-by-site) to list form submissions for a given site with the ability to filter by a `formElementId`. - Required scope | `users:read` + Required scope | `forms:read` Parameters ---------- site_id : str Unique identifier for a Site - user_id : str - Unique identifier for a User + form_id : str + Unique identifier for a Form + + offset : typing.Optional[int] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[int] + Maximum number of records to be returned (max limit: 100) request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - User + FormSubmissionList Request was successful Examples @@ -194,22 +215,29 @@ def get(self, site_id: str, user_id: str, *, request_options: typing.Optional[Re client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) - client.users.get( + client.sites.forms.list_submissions( site_id="580e63e98c9a982ac9b8b741", - user_id="580e63e98c9a982ac9b8b741", + form_id="580e63e98c9a982ac9b8b741", + offset=1, + limit=1, ) """ _response = self._client_wrapper.httpx_client.request( - f"sites/{jsonable_encoder(site_id)}/users/{jsonable_encoder(user_id)}", + f"sites/{jsonable_encoder(site_id)}/forms/{jsonable_encoder(form_id)}/submissions", + base_url=self._client_wrapper.get_environment().base, method="GET", + params={ + "offset": offset, + "limit": limit, + }, request_options=request_options, ) try: if 200 <= _response.status_code < 300: return typing.cast( - User, + FormSubmissionList, parse_obj_as( - type_=User, # type: ignore + type_=FormSubmissionList, # type: ignore object_=_response.json(), ), ) @@ -278,26 +306,29 @@ def get(self, site_id: str, user_id: str, *, request_options: typing.Optional[Re raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def delete(self, site_id: str, user_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: + def get_submission( + self, site_id: str, form_submission_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> FormSubmission: """ - Delete a User by ID + Get information about a form submission within a specific site. - Required scope | `users:write` + Required scope | `forms:read` Parameters ---------- site_id : str Unique identifier for a Site - user_id : str - Unique identifier for a User + form_submission_id : str + Unique identifier for a Form Submission request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - None + FormSubmission + Request was successful Examples -------- @@ -306,19 +337,26 @@ def delete(self, site_id: str, user_id: str, *, request_options: typing.Optional client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) - client.users.delete( + client.sites.forms.get_submission( site_id="580e63e98c9a982ac9b8b741", - user_id="580e63e98c9a982ac9b8b741", + form_submission_id="580e63e98c9a982ac9b8b741", ) """ _response = self._client_wrapper.httpx_client.request( - f"sites/{jsonable_encoder(site_id)}/users/{jsonable_encoder(user_id)}", - method="DELETE", + f"sites/{jsonable_encoder(site_id)}/form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, + method="GET", request_options=request_options, ) try: if 200 <= _response.status_code < 300: - return + return typing.cast( + FormSubmission, + parse_obj_as( + type_=FormSubmission, # type: ignore + object_=_response.json(), + ), + ) if _response.status_code == 400: raise BadRequestError( typing.cast( @@ -384,88 +422,50 @@ def delete(self, site_id: str, user_id: str, *, request_options: typing.Optional raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def update( - self, - site_id: str, - user_id: str, - *, - data: typing.Optional[UsersUpdateRequestData] = OMIT, - access_groups: typing.Optional[typing.Sequence[str]] = OMIT, - request_options: typing.Optional[RequestOptions] = None, - ) -> User: + def delete_submission( + self, site_id: str, form_submission_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: """ - Update a User by ID + Delete a form submission within a specific site. - Required scope | `users:write` - - The email and password - fields cannot be updated using this endpoint + Required scope | `forms:write` Parameters ---------- site_id : str Unique identifier for a Site - user_id : str - Unique identifier for a User - - data : typing.Optional[UsersUpdateRequestData] - - access_groups : typing.Optional[typing.Sequence[str]] - An array of access group slugs. Access groups are assigned to the user as type `admin` and the user remains in the group until removed. - + form_submission_id : str + Unique identifier for a Form Submission request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - User - Request was successful + None Examples -------- from webflow import Webflow - from webflow.resources.users import UsersUpdateRequestData client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) - client.users.update( + client.sites.forms.delete_submission( site_id="580e63e98c9a982ac9b8b741", - user_id="580e63e98c9a982ac9b8b741", - data=UsersUpdateRequestData( - name="Some One", - accept_privacy=False, - accept_communications=False, - ), - access_groups=["webflowers", "platinum", "free-tier"], + form_submission_id="580e63e98c9a982ac9b8b741", ) """ _response = self._client_wrapper.httpx_client.request( - f"sites/{jsonable_encoder(site_id)}/users/{jsonable_encoder(user_id)}", - method="PATCH", - json={ - "data": convert_and_respect_annotation_metadata( - object_=data, annotation=UsersUpdateRequestData, direction="write" - ), - "accessGroups": access_groups, - }, - headers={ - "content-type": "application/json", - }, + f"sites/{jsonable_encoder(site_id)}/form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, + method="DELETE", request_options=request_options, - omit=OMIT, ) try: if 200 <= _response.status_code < 300: - return typing.cast( - User, - parse_obj_as( - type_=User, # type: ignore - object_=_response.json(), - ), - ) + return if _response.status_code == 400: raise BadRequestError( typing.cast( @@ -506,6 +506,16 @@ def update( ), ) ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) if _response.status_code == 429: raise TooManyRequestsError( typing.cast( @@ -531,39 +541,36 @@ def update( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def invite( + def update_submission( self, site_id: str, + form_submission_id: str, *, - email: str, - access_groups: typing.Optional[typing.Sequence[str]] = OMIT, + form_submission_data: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> User: + ) -> FormSubmission: """ - Create and invite a user with an email address. + Update hidden fields on a form submission within a specific site. - The user will be sent and invite via email, which they will need to accept in order to join paid any paid access group. - - Required scope | `users:write` + Required scope | `forms:write` Parameters ---------- site_id : str Unique identifier for a Site - email : str - Email address of user to send invite to - - access_groups : typing.Optional[typing.Sequence[str]] - An array of access group slugs. Access groups are assigned to the user as type `admin` and the user remains in the group until removed. + form_submission_id : str + Unique identifier for a Form Submission + form_submission_data : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] + An existing **hidden field** defined on the form schema, and the corresponding value to set request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - User + FormSubmission Request was successful Examples @@ -573,18 +580,17 @@ def invite( client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) - client.users.invite( + client.sites.forms.update_submission( site_id="580e63e98c9a982ac9b8b741", - email="some.one@home.com", - access_groups=["webflowers"], + form_submission_id="580e63e98c9a982ac9b8b741", ) """ _response = self._client_wrapper.httpx_client.request( - f"sites/{jsonable_encoder(site_id)}/users/invite", - method="POST", + f"sites/{jsonable_encoder(site_id)}/form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, + method="PATCH", json={ - "email": email, - "accessGroups": access_groups, + "formSubmissionData": form_submission_data, }, headers={ "content-type": "application/json", @@ -595,9 +601,9 @@ def invite( try: if 200 <= _response.status_code < 300: return typing.cast( - User, + FormSubmission, parse_obj_as( - type_=User, # type: ignore + type_=FormSubmission, # type: ignore object_=_response.json(), ), ) @@ -677,48 +683,52 @@ def invite( raise ApiError(status_code=_response.status_code, body=_response_json) -class AsyncUsersClient: +class AsyncFormsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper - async def list( + async def list_submissions_by_site( self, site_id: str, *, - offset: typing.Optional[float] = None, - limit: typing.Optional[float] = None, - sort: typing.Optional[UsersListRequestSort] = None, + element_id: typing.Optional[str] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> UserList: + ) -> FormSubmissionList: """ - Get a list of users for a site + List all form submissions for a given site with the ability to filter submissions by a centralized `elementId`. + + Add `elementId` when you want to filter form submissions to a specific form in a site. You can get the `elementId` from the [List forms endpoint](/data/reference/forms/forms/list) (displayed as `formElementId` in the response). - Required scope | `users:read` + + When a form is used in a Webflow component definition, each instance of the component will yield a unique form. Adding the `elementId` in this request ensures this API response includes all submissions from that core form, wherever that form is used in instantiated components. + + + Use the [List Form Submissions endpoint](/data/reference/forms/form-submissions/list-submissions) to list form submissions for a given form ID. + + Required scope | `forms:read` Parameters ---------- site_id : str Unique identifier for a Site - offset : typing.Optional[float] + element_id : typing.Optional[str] + Identifier for an element + + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records - limit : typing.Optional[float] + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) - sort : typing.Optional[UsersListRequestSort] - Sort string to use when ordering users - - Example(`CreatedOn`, `Email`, `Status`, `LastLogin`, `UpdatedOn`). - - Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`) - request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - UserList + FormSubmissionList Request was successful Examples @@ -733,29 +743,33 @@ async def list( async def main() -> None: - await client.users.list( + await client.sites.forms.list_submissions_by_site( site_id="580e63e98c9a982ac9b8b741", + element_id="18259716-3e5a-646a-5f41-5dc4b9405aa0", + offset=1, + limit=1, ) asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - f"sites/{jsonable_encoder(site_id)}/users", + f"sites/{jsonable_encoder(site_id)}/form_submissions", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ + "elementId": element_id, "offset": offset, "limit": limit, - "sort": sort, }, request_options=request_options, ) try: if 200 <= _response.status_code < 300: return typing.cast( - UserList, + FormSubmissionList, parse_obj_as( - type_=UserList, # type: ignore + type_=FormSubmissionList, # type: ignore object_=_response.json(), ), ) @@ -824,26 +838,42 @@ async def main() -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def get(self, site_id: str, user_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> User: + async def list_submissions( + self, + site_id: str, + form_id: str, + *, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> FormSubmissionList: """ - Get a User by ID + List form submissions for a given form ID within a specific site. + + Use the [List Form Submissions by Site endpoint](/data/reference/forms/form-submissions/list-submissions-by-site) to list form submissions for a given site with the ability to filter by a `formElementId`. - Required scope | `users:read` + Required scope | `forms:read` Parameters ---------- site_id : str Unique identifier for a Site - user_id : str - Unique identifier for a User + form_id : str + Unique identifier for a Form + + offset : typing.Optional[int] + Offset used for pagination if the results have more than limit records + + limit : typing.Optional[int] + Maximum number of records to be returned (max limit: 100) request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - User + FormSubmissionList Request was successful Examples @@ -858,25 +888,32 @@ async def get(self, site_id: str, user_id: str, *, request_options: typing.Optio async def main() -> None: - await client.users.get( + await client.sites.forms.list_submissions( site_id="580e63e98c9a982ac9b8b741", - user_id="580e63e98c9a982ac9b8b741", + form_id="580e63e98c9a982ac9b8b741", + offset=1, + limit=1, ) asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - f"sites/{jsonable_encoder(site_id)}/users/{jsonable_encoder(user_id)}", + f"sites/{jsonable_encoder(site_id)}/forms/{jsonable_encoder(form_id)}/submissions", + base_url=self._client_wrapper.get_environment().base, method="GET", + params={ + "offset": offset, + "limit": limit, + }, request_options=request_options, ) try: if 200 <= _response.status_code < 300: return typing.cast( - User, + FormSubmissionList, parse_obj_as( - type_=User, # type: ignore + type_=FormSubmissionList, # type: ignore object_=_response.json(), ), ) @@ -945,28 +982,29 @@ async def main() -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def delete( - self, site_id: str, user_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> None: + async def get_submission( + self, site_id: str, form_submission_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> FormSubmission: """ - Delete a User by ID + Get information about a form submission within a specific site. - Required scope | `users:write` + Required scope | `forms:read` Parameters ---------- site_id : str Unique identifier for a Site - user_id : str - Unique identifier for a User + form_submission_id : str + Unique identifier for a Form Submission request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - None + FormSubmission + Request was successful Examples -------- @@ -980,22 +1018,29 @@ async def delete( async def main() -> None: - await client.users.delete( + await client.sites.forms.get_submission( site_id="580e63e98c9a982ac9b8b741", - user_id="580e63e98c9a982ac9b8b741", + form_submission_id="580e63e98c9a982ac9b8b741", ) asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - f"sites/{jsonable_encoder(site_id)}/users/{jsonable_encoder(user_id)}", - method="DELETE", + f"sites/{jsonable_encoder(site_id)}/form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, + method="GET", request_options=request_options, ) try: if 200 <= _response.status_code < 300: - return + return typing.cast( + FormSubmission, + parse_obj_as( + type_=FormSubmission, # type: ignore + object_=_response.json(), + ), + ) if _response.status_code == 400: raise BadRequestError( typing.cast( @@ -1061,51 +1106,34 @@ async def main() -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def update( - self, - site_id: str, - user_id: str, - *, - data: typing.Optional[UsersUpdateRequestData] = OMIT, - access_groups: typing.Optional[typing.Sequence[str]] = OMIT, - request_options: typing.Optional[RequestOptions] = None, - ) -> User: + async def delete_submission( + self, site_id: str, form_submission_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: """ - Update a User by ID - - Required scope | `users:write` + Delete a form submission within a specific site. - The email and password - fields cannot be updated using this endpoint + Required scope | `forms:write` Parameters ---------- site_id : str Unique identifier for a Site - user_id : str - Unique identifier for a User - - data : typing.Optional[UsersUpdateRequestData] - - access_groups : typing.Optional[typing.Sequence[str]] - An array of access group slugs. Access groups are assigned to the user as type `admin` and the user remains in the group until removed. - + form_submission_id : str + Unique identifier for a Form Submission request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - User - Request was successful + None Examples -------- import asyncio from webflow import AsyncWebflow - from webflow.resources.users import UsersUpdateRequestData client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", @@ -1113,44 +1141,23 @@ async def update( async def main() -> None: - await client.users.update( + await client.sites.forms.delete_submission( site_id="580e63e98c9a982ac9b8b741", - user_id="580e63e98c9a982ac9b8b741", - data=UsersUpdateRequestData( - name="Some One", - accept_privacy=False, - accept_communications=False, - ), - access_groups=["webflowers", "platinum", "free-tier"], + form_submission_id="580e63e98c9a982ac9b8b741", ) asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - f"sites/{jsonable_encoder(site_id)}/users/{jsonable_encoder(user_id)}", - method="PATCH", - json={ - "data": convert_and_respect_annotation_metadata( - object_=data, annotation=UsersUpdateRequestData, direction="write" - ), - "accessGroups": access_groups, - }, - headers={ - "content-type": "application/json", - }, + f"sites/{jsonable_encoder(site_id)}/form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, + method="DELETE", request_options=request_options, - omit=OMIT, ) try: if 200 <= _response.status_code < 300: - return typing.cast( - User, - parse_obj_as( - type_=User, # type: ignore - object_=_response.json(), - ), - ) + return if _response.status_code == 400: raise BadRequestError( typing.cast( @@ -1191,6 +1198,16 @@ async def main() -> None: ), ) ) + if _response.status_code == 409: + raise ConflictError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) if _response.status_code == 429: raise TooManyRequestsError( typing.cast( @@ -1216,39 +1233,36 @@ async def main() -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def invite( + async def update_submission( self, site_id: str, + form_submission_id: str, *, - email: str, - access_groups: typing.Optional[typing.Sequence[str]] = OMIT, + form_submission_data: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> User: + ) -> FormSubmission: """ - Create and invite a user with an email address. - - The user will be sent and invite via email, which they will need to accept in order to join paid any paid access group. + Update hidden fields on a form submission within a specific site. - Required scope | `users:write` + Required scope | `forms:write` Parameters ---------- site_id : str Unique identifier for a Site - email : str - Email address of user to send invite to - - access_groups : typing.Optional[typing.Sequence[str]] - An array of access group slugs. Access groups are assigned to the user as type `admin` and the user remains in the group until removed. + form_submission_id : str + Unique identifier for a Form Submission + form_submission_data : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] + An existing **hidden field** defined on the form schema, and the corresponding value to set request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - User + FormSubmission Request was successful Examples @@ -1263,21 +1277,20 @@ async def invite( async def main() -> None: - await client.users.invite( + await client.sites.forms.update_submission( site_id="580e63e98c9a982ac9b8b741", - email="some.one@home.com", - access_groups=["webflowers"], + form_submission_id="580e63e98c9a982ac9b8b741", ) asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - f"sites/{jsonable_encoder(site_id)}/users/invite", - method="POST", + f"sites/{jsonable_encoder(site_id)}/form_submissions/{jsonable_encoder(form_submission_id)}", + base_url=self._client_wrapper.get_environment().base, + method="PATCH", json={ - "email": email, - "accessGroups": access_groups, + "formSubmissionData": form_submission_data, }, headers={ "content-type": "application/json", @@ -1288,9 +1301,9 @@ async def main() -> None: try: if 200 <= _response.status_code < 300: return typing.cast( - User, + FormSubmission, parse_obj_as( - type_=User, # type: ignore + type_=FormSubmission, # type: ignore object_=_response.json(), ), ) diff --git a/src/webflow/resources/sites/resources/plans/client.py b/src/webflow/resources/sites/resources/plans/client.py index 291231a..a3309bb 100644 --- a/src/webflow/resources/sites/resources/plans/client.py +++ b/src/webflow/resources/sites/resources/plans/client.py @@ -25,6 +25,8 @@ def get_site_plan(self, site_id: str, *, request_options: typing.Optional[Reques """ Get site plan details for the specified Site. + This endpoint requires an Enterprise workspace. + Required scope | `sites:read` Parameters @@ -53,6 +55,7 @@ def get_site_plan(self, site_id: str, *, request_options: typing.Optional[Reques """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/plan", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -129,6 +132,8 @@ async def get_site_plan(self, site_id: str, *, request_options: typing.Optional[ """ Get site plan details for the specified Site. + This endpoint requires an Enterprise workspace. + Required scope | `sites:read` Parameters @@ -165,6 +170,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/plan", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) diff --git a/src/webflow/resources/sites/resources/redirects/client.py b/src/webflow/resources/sites/resources/redirects/client.py index 4bc0e7b..1ac17b4 100644 --- a/src/webflow/resources/sites/resources/redirects/client.py +++ b/src/webflow/resources/sites/resources/redirects/client.py @@ -27,10 +27,11 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Redirects: """ - Fetch a list of all URL redirect rules configured for a specific site. + Fetch a list of all 301 redirect rules configured for a specific site. Use this endpoint to review, audit, or manage the redirection rules that control how traffic is rerouted on your site. + This endpoint requires an Enterprise workspace. Required scope: `sites:read` @@ -60,6 +61,7 @@ def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/redirects", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -137,10 +139,12 @@ def create( request_options: typing.Optional[RequestOptions] = None, ) -> Redirect: """ - Add a new URL redirection rule to a site. + Add a new 301 redirection rule to a site. This endpoint allows you to define a source path (`fromUrl`) and its corresponding destination path (`toUrl`), which will dictate how traffic is rerouted on your site. This is useful for managing site changes, restructuring URLs, or handling outdated links. + This endpoint requires an Enterprise workspace. + Required scope: `sites:write` Parameters @@ -181,6 +185,7 @@ def create( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/redirects", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "id": id, @@ -258,8 +263,12 @@ def delete( self, site_id: str, redirect_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> Redirects: """ - Remove a URL redirection rule from a site. + Remove a 301 redirection rule from a site. + This is useful for cleaning up outdated or unnecessary redirects, ensuring that your site's routing behavior remains efficient and up-to-date. + + This endpoint requires an Enterprise workspace. + Required scope: `sites:write` Parameters @@ -292,6 +301,7 @@ def delete( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/redirects/{jsonable_encoder(redirect_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -370,7 +380,10 @@ def update( request_options: typing.Optional[RequestOptions] = None, ) -> Redirect: """ - Update a URL redirection rule from a site. + Update a 301 redirection rule from a site. + + This endpoint requires an Enterprise workspace. + Required scope: `sites:write` Parameters @@ -415,6 +428,7 @@ def update( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/redirects/{jsonable_encoder(redirect_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "id": id, @@ -495,10 +509,11 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): async def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Redirects: """ - Fetch a list of all URL redirect rules configured for a specific site. + Fetch a list of all 301 redirect rules configured for a specific site. Use this endpoint to review, audit, or manage the redirection rules that control how traffic is rerouted on your site. + This endpoint requires an Enterprise workspace. Required scope: `sites:read` @@ -536,6 +551,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/redirects", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -613,10 +629,12 @@ async def create( request_options: typing.Optional[RequestOptions] = None, ) -> Redirect: """ - Add a new URL redirection rule to a site. + Add a new 301 redirection rule to a site. This endpoint allows you to define a source path (`fromUrl`) and its corresponding destination path (`toUrl`), which will dictate how traffic is rerouted on your site. This is useful for managing site changes, restructuring URLs, or handling outdated links. + This endpoint requires an Enterprise workspace. + Required scope: `sites:write` Parameters @@ -665,6 +683,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/redirects", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "id": id, @@ -742,8 +761,12 @@ async def delete( self, site_id: str, redirect_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> Redirects: """ - Remove a URL redirection rule from a site. + Remove a 301 redirection rule from a site. + This is useful for cleaning up outdated or unnecessary redirects, ensuring that your site's routing behavior remains efficient and up-to-date. + + This endpoint requires an Enterprise workspace. + Required scope: `sites:write` Parameters @@ -784,6 +807,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/redirects/{jsonable_encoder(redirect_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -862,7 +886,10 @@ async def update( request_options: typing.Optional[RequestOptions] = None, ) -> Redirect: """ - Update a URL redirection rule from a site. + Update a 301 redirection rule from a site. + + This endpoint requires an Enterprise workspace. + Required scope: `sites:write` Parameters @@ -915,6 +942,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/redirects/{jsonable_encoder(redirect_id)}", + base_url=self._client_wrapper.get_environment().base, method="PATCH", json={ "id": id, diff --git a/src/webflow/types/duplicate_user_email.py b/src/webflow/resources/sites/resources/robots_txt/__init__.py similarity index 50% rename from src/webflow/types/duplicate_user_email.py rename to src/webflow/resources/sites/resources/robots_txt/__init__.py index 4a44039..f3ea265 100644 --- a/src/webflow/types/duplicate_user_email.py +++ b/src/webflow/resources/sites/resources/robots_txt/__init__.py @@ -1,5 +1,2 @@ # This file was auto-generated by Fern from our API Definition. -import typing - -DuplicateUserEmail = typing.Optional[typing.Any] diff --git a/src/webflow/resources/sites/resources/robots_txt/client.py b/src/webflow/resources/sites/resources/robots_txt/client.py new file mode 100644 index 0000000..a0bc59b --- /dev/null +++ b/src/webflow/resources/sites/resources/robots_txt/client.py @@ -0,0 +1,1050 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from .....core.client_wrapper import SyncClientWrapper +from .....core.request_options import RequestOptions +from .....types.robots import Robots +from .....core.jsonable_encoder import jsonable_encoder +from .....core.pydantic_utilities import parse_obj_as +from .....errors.bad_request_error import BadRequestError +from .....errors.unauthorized_error import UnauthorizedError +from .....types.error import Error +from .....errors.not_found_error import NotFoundError +from .....errors.too_many_requests_error import TooManyRequestsError +from .....errors.internal_server_error import InternalServerError +from json.decoder import JSONDecodeError +from .....core.api_error import ApiError +from .....types.robots_rules_item import RobotsRulesItem +from .....core.serialization import convert_and_respect_annotation_metadata +from .....core.client_wrapper import AsyncClientWrapper + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RobotsTxtClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def get(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Robots: + """ + Retrieve the robots.txt configuration for various user agents. + + This endpoint requires an Enterprise workspace. + + Required scope: `site_config:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Robots + Request was successful + + Examples + -------- + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.robots_txt.get( + site_id="580e63e98c9a982ac9b8b741", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/robots_txt", + base_url=self._client_wrapper.get_environment().base, + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + Robots, + parse_obj_as( + type_=Robots, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def put( + self, + site_id: str, + *, + rules: typing.Optional[typing.Sequence[RobotsRulesItem]] = OMIT, + sitemap: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> Robots: + """ + Replace the `robots.txt` configuration for various user agents. + + This endpoint requires an Enterprise workspace. + + Required scope | `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + rules : typing.Optional[typing.Sequence[RobotsRulesItem]] + List of rules for user agents. + + sitemap : typing.Optional[str] + URL to the sitemap. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Robots + Request was successful + + Examples + -------- + from webflow import RobotsRulesItem, Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.robots_txt.put( + site_id="580e63e98c9a982ac9b8b741", + rules=[ + RobotsRulesItem( + user_agent="googlebot", + allows=["/public"], + disallows=["/vogon-poetry", "/total-perspective-vortex"], + ) + ], + sitemap="https://heartofgold.ship/sitemap.xml", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/robots_txt", + base_url=self._client_wrapper.get_environment().base, + method="PUT", + json={ + "rules": convert_and_respect_annotation_metadata( + object_=rules, annotation=typing.Sequence[RobotsRulesItem], direction="write" + ), + "sitemap": sitemap, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + Robots, + parse_obj_as( + type_=Robots, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def delete( + self, + site_id: str, + *, + rules: typing.Optional[typing.Sequence[RobotsRulesItem]] = OMIT, + sitemap: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> Robots: + """ + Remove specific rules for a user-agent in your `robots.txt` file. To delete all rules for a user-agent, provide an empty rule set. This will remove the user-agent's entry entirely, leaving it subject to your site's default crawling behavior. + + **Note:** Deleting a user-agent with no rules will make the user-agent's access unrestricted unless other directives apply. + + This endpoint requires an Enterprise workspace. + + Required scope: `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + rules : typing.Optional[typing.Sequence[RobotsRulesItem]] + List of rules for user agents. + + sitemap : typing.Optional[str] + URL to the sitemap. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Robots + Request was successful + + Examples + -------- + from webflow import RobotsRulesItem, Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.robots_txt.delete( + site_id="580e63e98c9a982ac9b8b741", + rules=[ + RobotsRulesItem( + user_agent="*", + allows=["/public"], + disallows=["/bubbles"], + ) + ], + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/robots_txt", + base_url=self._client_wrapper.get_environment().base, + method="DELETE", + json={ + "rules": convert_and_respect_annotation_metadata( + object_=rules, annotation=typing.Sequence[RobotsRulesItem], direction="write" + ), + "sitemap": sitemap, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + Robots, + parse_obj_as( + type_=Robots, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def patch( + self, + site_id: str, + *, + rules: typing.Optional[typing.Sequence[RobotsRulesItem]] = OMIT, + sitemap: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> Robots: + """ + Update the `robots.txt` configuration for various user agents. + + This endpoint requires an Enterprise workspace. + + Required scope | `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + rules : typing.Optional[typing.Sequence[RobotsRulesItem]] + List of rules for user agents. + + sitemap : typing.Optional[str] + URL to the sitemap. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Robots + Request was successful + + Examples + -------- + from webflow import RobotsRulesItem, Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.robots_txt.patch( + site_id="580e63e98c9a982ac9b8b741", + rules=[ + RobotsRulesItem( + user_agent="googlebot", + allows=["/public"], + disallows=["/vogon-poetry", "/total-perspective-vortex"], + ) + ], + sitemap="https://heartofgold.ship/sitemap.xml", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/robots_txt", + base_url=self._client_wrapper.get_environment().base, + method="PATCH", + json={ + "rules": convert_and_respect_annotation_metadata( + object_=rules, annotation=typing.Sequence[RobotsRulesItem], direction="write" + ), + "sitemap": sitemap, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + Robots, + parse_obj_as( + type_=Robots, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + +class AsyncRobotsTxtClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def get(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Robots: + """ + Retrieve the robots.txt configuration for various user agents. + + This endpoint requires an Enterprise workspace. + + Required scope: `site_config:read` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Robots + Request was successful + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.robots_txt.get( + site_id="580e63e98c9a982ac9b8b741", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/robots_txt", + base_url=self._client_wrapper.get_environment().base, + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + Robots, + parse_obj_as( + type_=Robots, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def put( + self, + site_id: str, + *, + rules: typing.Optional[typing.Sequence[RobotsRulesItem]] = OMIT, + sitemap: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> Robots: + """ + Replace the `robots.txt` configuration for various user agents. + + This endpoint requires an Enterprise workspace. + + Required scope | `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + rules : typing.Optional[typing.Sequence[RobotsRulesItem]] + List of rules for user agents. + + sitemap : typing.Optional[str] + URL to the sitemap. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Robots + Request was successful + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow, RobotsRulesItem + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.robots_txt.put( + site_id="580e63e98c9a982ac9b8b741", + rules=[ + RobotsRulesItem( + user_agent="googlebot", + allows=["/public"], + disallows=["/vogon-poetry", "/total-perspective-vortex"], + ) + ], + sitemap="https://heartofgold.ship/sitemap.xml", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/robots_txt", + base_url=self._client_wrapper.get_environment().base, + method="PUT", + json={ + "rules": convert_and_respect_annotation_metadata( + object_=rules, annotation=typing.Sequence[RobotsRulesItem], direction="write" + ), + "sitemap": sitemap, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + Robots, + parse_obj_as( + type_=Robots, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def delete( + self, + site_id: str, + *, + rules: typing.Optional[typing.Sequence[RobotsRulesItem]] = OMIT, + sitemap: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> Robots: + """ + Remove specific rules for a user-agent in your `robots.txt` file. To delete all rules for a user-agent, provide an empty rule set. This will remove the user-agent's entry entirely, leaving it subject to your site's default crawling behavior. + + **Note:** Deleting a user-agent with no rules will make the user-agent's access unrestricted unless other directives apply. + + This endpoint requires an Enterprise workspace. + + Required scope: `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + rules : typing.Optional[typing.Sequence[RobotsRulesItem]] + List of rules for user agents. + + sitemap : typing.Optional[str] + URL to the sitemap. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Robots + Request was successful + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow, RobotsRulesItem + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.robots_txt.delete( + site_id="580e63e98c9a982ac9b8b741", + rules=[ + RobotsRulesItem( + user_agent="*", + allows=["/public"], + disallows=["/bubbles"], + ) + ], + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/robots_txt", + base_url=self._client_wrapper.get_environment().base, + method="DELETE", + json={ + "rules": convert_and_respect_annotation_metadata( + object_=rules, annotation=typing.Sequence[RobotsRulesItem], direction="write" + ), + "sitemap": sitemap, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + Robots, + parse_obj_as( + type_=Robots, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def patch( + self, + site_id: str, + *, + rules: typing.Optional[typing.Sequence[RobotsRulesItem]] = OMIT, + sitemap: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> Robots: + """ + Update the `robots.txt` configuration for various user agents. + + This endpoint requires an Enterprise workspace. + + Required scope | `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + rules : typing.Optional[typing.Sequence[RobotsRulesItem]] + List of rules for user agents. + + sitemap : typing.Optional[str] + URL to the sitemap. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Robots + Request was successful + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow, RobotsRulesItem + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.robots_txt.patch( + site_id="580e63e98c9a982ac9b8b741", + rules=[ + RobotsRulesItem( + user_agent="googlebot", + allows=["/public"], + disallows=["/vogon-poetry", "/total-perspective-vortex"], + ) + ], + sitemap="https://heartofgold.ship/sitemap.xml", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/robots_txt", + base_url=self._client_wrapper.get_environment().base, + method="PATCH", + json={ + "rules": convert_and_respect_annotation_metadata( + object_=rules, annotation=typing.Sequence[RobotsRulesItem], direction="write" + ), + "sitemap": sitemap, + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return typing.cast( + Robots, + parse_obj_as( + type_=Robots, # type: ignore + object_=_response.json(), + ), + ) + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) diff --git a/src/webflow/resources/sites/resources/scripts/client.py b/src/webflow/resources/sites/resources/scripts/client.py index 1954842..7966e56 100644 --- a/src/webflow/resources/sites/resources/scripts/client.py +++ b/src/webflow/resources/sites/resources/scripts/client.py @@ -31,9 +31,11 @@ def get_custom_code( self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> ScriptApplyList: """ - Get all registered scripts that have been applied to a specific Site. + Get all scripts applied to a site by the App. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:read` @@ -63,6 +65,7 @@ def get_custom_code( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -140,13 +143,11 @@ def upsert_custom_code( request_options: typing.Optional[RequestOptions] = None, ) -> ScriptApplyList: """ - Add a registered script to a Site. + Apply registered scripts to a site. If you have multiple scripts your App needs to apply or maintain on a site, ensure they are always included in the request body for this endpoint. To remove individual scripts, simply call this endpoint without the script in the request body. - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` @@ -198,6 +199,7 @@ def upsert_custom_code( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="PUT", json={ "scripts": convert_and_respect_annotation_metadata( @@ -275,9 +277,11 @@ def upsert_custom_code( def delete_custom_code(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: """ - Delete the custom code block that an app created for a Site + Remove all scripts from a site applied by the App. This endpoint will not remove scripts from the site's registered scripts. + + To remove individual scripts applied by the App, use the [Add/Update Custom Code](/data/reference/custom-code/custom-code-sites/upsert-custom-code) endpoint. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + Access to this endpoint requires a bearer token obtained from an [OAuth Code Grant Flow](/data/reference/oauth-app). Required scope | `custom_code:write` @@ -306,6 +310,7 @@ def delete_custom_code(self, site_id: str, *, request_options: typing.Optional[R """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -371,14 +376,18 @@ def list_custom_code_blocks( self, site_id: str, *, - offset: typing.Optional[float] = None, - limit: typing.Optional[float] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ListCustomCodeBlocks: """ - Get all instances of Custom Code applied to a Site or Pages. + Get a list of scripts that have been applied to a site and/or individual pages. + + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:read` @@ -387,10 +396,10 @@ def list_custom_code_blocks( site_id : str Unique identifier for a Site - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records - limit : typing.Optional[float] + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) request_options : typing.Optional[RequestOptions] @@ -410,10 +419,13 @@ def list_custom_code_blocks( ) client.sites.scripts.list_custom_code_blocks( site_id="580e63e98c9a982ac9b8b741", + offset=1, + limit=1, ) """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_code/blocks", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "offset": offset, @@ -494,9 +506,11 @@ async def get_custom_code( self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> ScriptApplyList: """ - Get all registered scripts that have been applied to a specific Site. + Get all scripts applied to a site by the App. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:read` @@ -534,6 +548,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -611,13 +626,11 @@ async def upsert_custom_code( request_options: typing.Optional[RequestOptions] = None, ) -> ScriptApplyList: """ - Add a registered script to a Site. + Apply registered scripts to a site. If you have multiple scripts your App needs to apply or maintain on a site, ensure they are always included in the request body for this endpoint. To remove individual scripts, simply call this endpoint without the script in the request body. - In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered - to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate - `custom_code` endpoints. - - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:write` @@ -677,6 +690,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="PUT", json={ "scripts": convert_and_respect_annotation_metadata( @@ -756,9 +770,11 @@ async def delete_custom_code( self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> None: """ - Delete the custom code block that an app created for a Site + Remove all scripts from a site applied by the App. This endpoint will not remove scripts from the site's registered scripts. + + To remove individual scripts applied by the App, use the [Add/Update Custom Code](/data/reference/custom-code/custom-code-sites/upsert-custom-code) endpoint. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + Access to this endpoint requires a bearer token obtained from an [OAuth Code Grant Flow](/data/reference/oauth-app). Required scope | `custom_code:write` @@ -795,6 +811,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_code", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -860,14 +877,18 @@ async def list_custom_code_blocks( self, site_id: str, *, - offset: typing.Optional[float] = None, - limit: typing.Optional[float] = None, + offset: typing.Optional[int] = None, + limit: typing.Optional[int] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ListCustomCodeBlocks: """ - Get all instances of Custom Code applied to a Site or Pages. + Get a list of scripts that have been applied to a site and/or individual pages. + + + To apply a script to a site or page, the script must first be registered to a site via the [Register Script](/data/reference/custom-code/custom-code/register-hosted) endpoints. Once registered, the script can be applied to a Site or Page using the appropriate endpoints. - Access to this endpoint requires a bearer token from a [Data Client App](/data/docs/getting-started-data-clients). + See the documentation on [working with Custom Code](/data/docs/custom-code) for more information. + Required scope | `custom_code:read` @@ -876,10 +897,10 @@ async def list_custom_code_blocks( site_id : str Unique identifier for a Site - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records - limit : typing.Optional[float] + limit : typing.Optional[int] Maximum number of records to be returned (max limit: 100) request_options : typing.Optional[RequestOptions] @@ -904,6 +925,8 @@ async def list_custom_code_blocks( async def main() -> None: await client.sites.scripts.list_custom_code_blocks( site_id="580e63e98c9a982ac9b8b741", + offset=1, + limit=1, ) @@ -911,6 +934,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/custom_code/blocks", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ "offset": offset, diff --git a/src/webflow/resources/sites/resources/well_known/__init__.py b/src/webflow/resources/sites/resources/well_known/__init__.py new file mode 100644 index 0000000..323b6bd --- /dev/null +++ b/src/webflow/resources/sites/resources/well_known/__init__.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .types import WellKnownFileContentType + +__all__ = ["WellKnownFileContentType"] diff --git a/src/webflow/resources/sites/resources/well_known/client.py b/src/webflow/resources/sites/resources/well_known/client.py new file mode 100644 index 0000000..3bba9ab --- /dev/null +++ b/src/webflow/resources/sites/resources/well_known/client.py @@ -0,0 +1,534 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from .....core.client_wrapper import SyncClientWrapper +from .types.well_known_file_content_type import WellKnownFileContentType +from .....core.request_options import RequestOptions +from .....core.jsonable_encoder import jsonable_encoder +from .....errors.bad_request_error import BadRequestError +from .....core.pydantic_utilities import parse_obj_as +from .....errors.unauthorized_error import UnauthorizedError +from .....types.error import Error +from .....errors.not_found_error import NotFoundError +from .....errors.too_many_requests_error import TooManyRequestsError +from .....errors.internal_server_error import InternalServerError +from json.decoder import JSONDecodeError +from .....core.api_error import ApiError +from .....core.client_wrapper import AsyncClientWrapper + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class WellKnownClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def put( + self, + site_id: str, + *, + file_name: str, + file_data: str, + content_type: typing.Optional[WellKnownFileContentType] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> None: + """ + Upload a supported well-known file to a site. + + The current restrictions on well-known files are as follows: + - Each file must be smaller than 100kb + - Less than 30 total files + - Have one of the following file extensions (or no extension): `.txt`, `.json`, `.noext` + + + `.noext` is a special file extension that removes other extensions. For example, `apple-app-site-association.noext.txt` will be uploaded as `apple-app-site-association`. Use this extension for tools that have trouble uploading extensionless files. + + + This endpoint requires an Enterprise workspace. + + Required scope: `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + file_name : str + The name of the file + + file_data : str + The contents of the file + + content_type : typing.Optional[WellKnownFileContentType] + The content type of the file. Defaults to application/json + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.well_known.put( + site_id="580e63e98c9a982ac9b8b741", + file_name="apple-app-site-association.txt", + file_data='{\n "applinks": {\n "apps": [],\n "details": [\n {\n "appID": "ABCDE12345.com.example.app",\n "paths": [ "/*", "/some/path/*" ]\n }\n ]\n }\n}\n', + content_type="application/json", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/well_known", + base_url=self._client_wrapper.get_environment().base, + method="PUT", + json={ + "fileName": file_name, + "fileData": file_data, + "contentType": content_type, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def delete( + self, + site_id: str, + *, + file_names: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> None: + """ + Delete existing well-known files from a site. + + This endpoint requires an Enterprise workspace. + + Required scope: `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + file_names : typing.Optional[typing.Sequence[str]] + A list of file names to delete + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + from webflow import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.well_known.delete( + site_id="580e63e98c9a982ac9b8b741", + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/well_known", + base_url=self._client_wrapper.get_environment().base, + method="DELETE", + json={ + "fileNames": file_names, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + +class AsyncWellKnownClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def put( + self, + site_id: str, + *, + file_name: str, + file_data: str, + content_type: typing.Optional[WellKnownFileContentType] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> None: + """ + Upload a supported well-known file to a site. + + The current restrictions on well-known files are as follows: + - Each file must be smaller than 100kb + - Less than 30 total files + - Have one of the following file extensions (or no extension): `.txt`, `.json`, `.noext` + + + `.noext` is a special file extension that removes other extensions. For example, `apple-app-site-association.noext.txt` will be uploaded as `apple-app-site-association`. Use this extension for tools that have trouble uploading extensionless files. + + + This endpoint requires an Enterprise workspace. + + Required scope: `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + file_name : str + The name of the file + + file_data : str + The contents of the file + + content_type : typing.Optional[WellKnownFileContentType] + The content type of the file. Defaults to application/json + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.well_known.put( + site_id="580e63e98c9a982ac9b8b741", + file_name="apple-app-site-association.txt", + file_data='{\n "applinks": {\n "apps": [],\n "details": [\n {\n "appID": "ABCDE12345.com.example.app",\n "paths": [ "/*", "/some/path/*" ]\n }\n ]\n }\n}\n', + content_type="application/json", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/well_known", + base_url=self._client_wrapper.get_environment().base, + method="PUT", + json={ + "fileName": file_name, + "fileData": file_data, + "contentType": content_type, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def delete( + self, + site_id: str, + *, + file_names: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> None: + """ + Delete existing well-known files from a site. + + This endpoint requires an Enterprise workspace. + + Required scope: `site_config:write` + + Parameters + ---------- + site_id : str + Unique identifier for a Site + + file_names : typing.Optional[typing.Sequence[str]] + A list of file names to delete + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + import asyncio + + from webflow import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + + + async def main() -> None: + await client.sites.well_known.delete( + site_id="580e63e98c9a982ac9b8b741", + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"sites/{jsonable_encoder(site_id)}/well_known", + base_url=self._client_wrapper.get_environment().base, + method="DELETE", + json={ + "fileNames": file_names, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError( + typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 401: + raise UnauthorizedError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 404: + raise NotFoundError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 429: + raise TooManyRequestsError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + if _response.status_code == 500: + raise InternalServerError( + typing.cast( + Error, + parse_obj_as( + type_=Error, # type: ignore + object_=_response.json(), + ), + ) + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) diff --git a/src/webflow/resources/sites/resources/well_known/types/__init__.py b/src/webflow/resources/sites/resources/well_known/types/__init__.py new file mode 100644 index 0000000..4fc9c09 --- /dev/null +++ b/src/webflow/resources/sites/resources/well_known/types/__init__.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .well_known_file_content_type import WellKnownFileContentType + +__all__ = ["WellKnownFileContentType"] diff --git a/src/webflow/resources/sites/resources/well_known/types/well_known_file_content_type.py b/src/webflow/resources/sites/resources/well_known/types/well_known_file_content_type.py new file mode 100644 index 0000000..be135b4 --- /dev/null +++ b/src/webflow/resources/sites/resources/well_known/types/well_known_file_content_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +WellKnownFileContentType = typing.Union[typing.Literal["application/json", "text/plain"], typing.Any] diff --git a/src/webflow/resources/token/client.py b/src/webflow/resources/token/client.py index 628ce3a..d8cfd16 100644 --- a/src/webflow/resources/token/client.py +++ b/src/webflow/resources/token/client.py @@ -45,6 +45,7 @@ def authorized_by(self, *, request_options: typing.Optional[RequestOptions] = No """ _response = self._client_wrapper.httpx_client.request( "token/authorized_by", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -109,6 +110,7 @@ def introspect(self, *, request_options: typing.Optional[RequestOptions] = None) """ _response = self._client_wrapper.httpx_client.request( "token/introspect", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -176,6 +178,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( "token/authorized_by", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -248,6 +251,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( "token/introspect", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) diff --git a/src/webflow/resources/users/__init__.py b/src/webflow/resources/users/__init__.py deleted file mode 100644 index 88e72a2..0000000 --- a/src/webflow/resources/users/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from .types import UsersListRequestSort, UsersUpdateRequestData - -__all__ = ["UsersListRequestSort", "UsersUpdateRequestData"] diff --git a/src/webflow/resources/users/types/__init__.py b/src/webflow/resources/users/types/__init__.py deleted file mode 100644 index cadf367..0000000 --- a/src/webflow/resources/users/types/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from .users_list_request_sort import UsersListRequestSort -from .users_update_request_data import UsersUpdateRequestData - -__all__ = ["UsersListRequestSort", "UsersUpdateRequestData"] diff --git a/src/webflow/resources/users/types/users_list_request_sort.py b/src/webflow/resources/users/types/users_list_request_sort.py deleted file mode 100644 index e4143a4..0000000 --- a/src/webflow/resources/users/types/users_list_request_sort.py +++ /dev/null @@ -1,19 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -UsersListRequestSort = typing.Union[ - typing.Literal[ - "CreatedOn", - "-CreatedOn", - "Email", - "-Email", - "Status", - "-Status", - "LastLogin", - "-LastLogin", - "UpdatedOn", - "-UpdatedOn", - ], - typing.Any, -] diff --git a/src/webflow/resources/users/types/users_update_request_data.py b/src/webflow/resources/users/types/users_update_request_data.py deleted file mode 100644 index 919406c..0000000 --- a/src/webflow/resources/users/types/users_update_request_data.py +++ /dev/null @@ -1,38 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from ....core.pydantic_utilities import UniversalBaseModel -import typing -import pydantic -import typing_extensions -from ....core.serialization import FieldMetadata -from ....core.pydantic_utilities import IS_PYDANTIC_V2 - - -class UsersUpdateRequestData(UniversalBaseModel): - name: typing.Optional[str] = pydantic.Field(default=None) - """ - The name of the user - """ - - accept_privacy: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="accept-privacy")] = ( - pydantic.Field(default=None) - ) - """ - Boolean indicating if the user has accepted the privacy policy - """ - - accept_communications: typing_extensions.Annotated[ - typing.Optional[bool], FieldMetadata(alias="accept-communications") - ] = pydantic.Field(default=None) - """ - Boolean indicating if the user has accepted to receive communications - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/webflow/resources/webhooks/client.py b/src/webflow/resources/webhooks/client.py index ded9a2f..c6821a9 100644 --- a/src/webflow/resources/webhooks/client.py +++ b/src/webflow/resources/webhooks/client.py @@ -61,6 +61,7 @@ def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/webhooks", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -212,6 +213,7 @@ def create( """ _response = self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id_)}/webhooks", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "id": id, @@ -324,6 +326,7 @@ def get(self, webhook_id: str, *, request_options: typing.Optional[RequestOption """ _response = self._client_wrapper.httpx_client.request( f"webhooks/{jsonable_encoder(webhook_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -422,6 +425,7 @@ def delete(self, webhook_id: str, *, request_options: typing.Optional[RequestOpt """ _response = self._client_wrapper.httpx_client.request( f"webhooks/{jsonable_encoder(webhook_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) @@ -528,6 +532,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id)}/webhooks", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -686,6 +691,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"sites/{jsonable_encoder(site_id_)}/webhooks", + base_url=self._client_wrapper.get_environment().base, method="POST", json={ "id": id, @@ -806,6 +812,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"webhooks/{jsonable_encoder(webhook_id)}", + base_url=self._client_wrapper.get_environment().base, method="GET", request_options=request_options, ) @@ -912,6 +919,7 @@ async def main() -> None: """ _response = await self._client_wrapper.httpx_client.request( f"webhooks/{jsonable_encoder(webhook_id)}", + base_url=self._client_wrapper.get_environment().base, method="DELETE", request_options=request_options, ) diff --git a/src/webflow/resources/workspaces/__init__.py b/src/webflow/resources/workspaces/__init__.py new file mode 100644 index 0000000..d6cc054 --- /dev/null +++ b/src/webflow/resources/workspaces/__init__.py @@ -0,0 +1,13 @@ +# This file was auto-generated by Fern from our API Definition. + +from .resources import ( + AuditLogsGetWorkspaceAuditLogsRequestEventType, + AuditLogsGetWorkspaceAuditLogsRequestSortOrder, + audit_logs, +) + +__all__ = [ + "AuditLogsGetWorkspaceAuditLogsRequestEventType", + "AuditLogsGetWorkspaceAuditLogsRequestSortOrder", + "audit_logs", +] diff --git a/src/webflow/resources/workspaces/client.py b/src/webflow/resources/workspaces/client.py new file mode 100644 index 0000000..de70ca5 --- /dev/null +++ b/src/webflow/resources/workspaces/client.py @@ -0,0 +1,18 @@ +# This file was auto-generated by Fern from our API Definition. + +from ...core.client_wrapper import SyncClientWrapper +from .resources.audit_logs.client import AuditLogsClient +from ...core.client_wrapper import AsyncClientWrapper +from .resources.audit_logs.client import AsyncAuditLogsClient + + +class WorkspacesClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + self.audit_logs = AuditLogsClient(client_wrapper=self._client_wrapper) + + +class AsyncWorkspacesClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + self.audit_logs = AsyncAuditLogsClient(client_wrapper=self._client_wrapper) diff --git a/src/webflow/resources/workspaces/resources/__init__.py b/src/webflow/resources/workspaces/resources/__init__.py new file mode 100644 index 0000000..0e96a0e --- /dev/null +++ b/src/webflow/resources/workspaces/resources/__init__.py @@ -0,0 +1,10 @@ +# This file was auto-generated by Fern from our API Definition. + +from . import audit_logs +from .audit_logs import AuditLogsGetWorkspaceAuditLogsRequestEventType, AuditLogsGetWorkspaceAuditLogsRequestSortOrder + +__all__ = [ + "AuditLogsGetWorkspaceAuditLogsRequestEventType", + "AuditLogsGetWorkspaceAuditLogsRequestSortOrder", + "audit_logs", +] diff --git a/src/webflow/resources/workspaces/resources/audit_logs/__init__.py b/src/webflow/resources/workspaces/resources/audit_logs/__init__.py new file mode 100644 index 0000000..dab3df1 --- /dev/null +++ b/src/webflow/resources/workspaces/resources/audit_logs/__init__.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .types import AuditLogsGetWorkspaceAuditLogsRequestEventType, AuditLogsGetWorkspaceAuditLogsRequestSortOrder + +__all__ = ["AuditLogsGetWorkspaceAuditLogsRequestEventType", "AuditLogsGetWorkspaceAuditLogsRequestSortOrder"] diff --git a/src/webflow/resources/access_groups/client.py b/src/webflow/resources/workspaces/resources/audit_logs/client.py similarity index 52% rename from src/webflow/resources/access_groups/client.py rename to src/webflow/resources/workspaces/resources/audit_logs/client.py index ee7668a..dcbded2 100644 --- a/src/webflow/resources/access_groups/client.py +++ b/src/webflow/resources/workspaces/resources/audit_logs/client.py @@ -1,105 +1,126 @@ # This file was auto-generated by Fern from our API Definition. -from ...core.client_wrapper import SyncClientWrapper +from .....core.client_wrapper import SyncClientWrapper import typing -from .types.access_groups_list_request_sort import AccessGroupsListRequestSort -from ...core.request_options import RequestOptions -from ...types.access_group_list import AccessGroupList -from ...core.jsonable_encoder import jsonable_encoder -from ...core.pydantic_utilities import parse_obj_as -from ...errors.bad_request_error import BadRequestError -from ...errors.unauthorized_error import UnauthorizedError -from ...types.error import Error -from ...errors.forbidden_error import ForbiddenError -from ...errors.not_found_error import NotFoundError -from ...errors.too_many_requests_error import TooManyRequestsError -from ...errors.internal_server_error import InternalServerError +from .types.audit_logs_get_workspace_audit_logs_request_sort_order import AuditLogsGetWorkspaceAuditLogsRequestSortOrder +from .types.audit_logs_get_workspace_audit_logs_request_event_type import AuditLogsGetWorkspaceAuditLogsRequestEventType +import datetime as dt +from .....core.request_options import RequestOptions +from .....types.workspace_audit_log_response import WorkspaceAuditLogResponse +from .....core.jsonable_encoder import jsonable_encoder +from .....core.datetime_utils import serialize_datetime +from .....core.pydantic_utilities import parse_obj_as +from .....errors.unauthorized_error import UnauthorizedError +from .....types.error import Error +from .....errors.forbidden_error import ForbiddenError +from .....errors.not_found_error import NotFoundError +from .....errors.too_many_requests_error import TooManyRequestsError +from .....errors.internal_server_error import InternalServerError from json.decoder import JSONDecodeError -from ...core.api_error import ApiError -from ...core.client_wrapper import AsyncClientWrapper +from .....core.api_error import ApiError +from .....core.client_wrapper import AsyncClientWrapper -class AccessGroupsClient: +class AuditLogsClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper - def list( + def get_workspace_audit_logs( self, - site_id: str, + workspace_id_or_slug: str, *, - offset: typing.Optional[float] = None, - limit: typing.Optional[float] = None, - sort: typing.Optional[AccessGroupsListRequestSort] = None, + limit: typing.Optional[int] = None, + offset: typing.Optional[int] = None, + sort_order: typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestSortOrder] = None, + event_type: typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestEventType] = None, + from_: typing.Optional[dt.datetime] = None, + to: typing.Optional[dt.datetime] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> AccessGroupList: + ) -> WorkspaceAuditLogResponse: """ - Get a list of access groups for a site + Get audit logs for a workspace. - Required scope | `users:read` + This endpoint requires an Enterprise workspace and a workspace token with the `workspace_activity:read` scope. Create a workspace token from your workspace dashboard integrations page to use this endpoint. + + Required scope | `workspace_activity:read` Parameters ---------- - site_id : str - Unique identifier for a Site + workspace_id_or_slug : str + Unique identifier or slug for a Workspace + + limit : typing.Optional[int] + Maximum number of records to be returned (max limit: 100) - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records - limit : typing.Optional[float] - Maximum number of records to be returned (max limit: 100) + sort_order : typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestSortOrder] + Sorts the results by asc or desc + + event_type : typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestEventType] + The event type to filter by - sort : typing.Optional[AccessGroupsListRequestSort] - Sort string to use when ordering access groups - Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`) + from_ : typing.Optional[dt.datetime] + The start date to filter by + + to : typing.Optional[dt.datetime] + The end date to filter by request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - AccessGroupList - Request was successful + WorkspaceAuditLogResponse + A list of workspace audit logs Examples -------- + import datetime + from webflow import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) - client.access_groups.list( - site_id="580e63e98c9a982ac9b8b741", + client.workspaces.audit_logs.get_workspace_audit_logs( + workspace_id_or_slug="hitchhikers-workspace", + limit=1, + offset=1, + sort_order="asc", + event_type="user_access", + from_=datetime.datetime.fromisoformat( + "2025-06-22 16:00:31+00:00", + ), + to=datetime.datetime.fromisoformat( + "2025-07-22 16:00:31+00:00", + ), ) """ _response = self._client_wrapper.httpx_client.request( - f"sites/{jsonable_encoder(site_id)}/accessgroups", + f"workspaces/{jsonable_encoder(workspace_id_or_slug)}/audit_logs", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ - "offset": offset, "limit": limit, - "sort": sort, + "offset": offset, + "sortOrder": sort_order, + "eventType": event_type, + "from": serialize_datetime(from_) if from_ is not None else None, + "to": serialize_datetime(to) if to is not None else None, }, request_options=request_options, ) try: if 200 <= _response.status_code < 300: return typing.cast( - AccessGroupList, + WorkspaceAuditLogResponse, parse_obj_as( - type_=AccessGroupList, # type: ignore + type_=WorkspaceAuditLogResponse, # type: ignore object_=_response.json(), ), ) - if _response.status_code == 400: - raise BadRequestError( - typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ) - ) if _response.status_code == 401: raise UnauthorizedError( typing.cast( @@ -156,50 +177,64 @@ def list( raise ApiError(status_code=_response.status_code, body=_response_json) -class AsyncAccessGroupsClient: +class AsyncAuditLogsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper - async def list( + async def get_workspace_audit_logs( self, - site_id: str, + workspace_id_or_slug: str, *, - offset: typing.Optional[float] = None, - limit: typing.Optional[float] = None, - sort: typing.Optional[AccessGroupsListRequestSort] = None, + limit: typing.Optional[int] = None, + offset: typing.Optional[int] = None, + sort_order: typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestSortOrder] = None, + event_type: typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestEventType] = None, + from_: typing.Optional[dt.datetime] = None, + to: typing.Optional[dt.datetime] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> AccessGroupList: + ) -> WorkspaceAuditLogResponse: """ - Get a list of access groups for a site + Get audit logs for a workspace. - Required scope | `users:read` + This endpoint requires an Enterprise workspace and a workspace token with the `workspace_activity:read` scope. Create a workspace token from your workspace dashboard integrations page to use this endpoint. + + Required scope | `workspace_activity:read` Parameters ---------- - site_id : str - Unique identifier for a Site + workspace_id_or_slug : str + Unique identifier or slug for a Workspace + + limit : typing.Optional[int] + Maximum number of records to be returned (max limit: 100) - offset : typing.Optional[float] + offset : typing.Optional[int] Offset used for pagination if the results have more than limit records - limit : typing.Optional[float] - Maximum number of records to be returned (max limit: 100) + sort_order : typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestSortOrder] + Sorts the results by asc or desc - sort : typing.Optional[AccessGroupsListRequestSort] - Sort string to use when ordering access groups - Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`) + event_type : typing.Optional[AuditLogsGetWorkspaceAuditLogsRequestEventType] + The event type to filter by + + from_ : typing.Optional[dt.datetime] + The start date to filter by + + to : typing.Optional[dt.datetime] + The end date to filter by request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - AccessGroupList - Request was successful + WorkspaceAuditLogResponse + A list of workspace audit logs Examples -------- import asyncio + import datetime from webflow import AsyncWebflow @@ -209,42 +244,46 @@ async def list( async def main() -> None: - await client.access_groups.list( - site_id="580e63e98c9a982ac9b8b741", + await client.workspaces.audit_logs.get_workspace_audit_logs( + workspace_id_or_slug="hitchhikers-workspace", + limit=1, + offset=1, + sort_order="asc", + event_type="user_access", + from_=datetime.datetime.fromisoformat( + "2025-06-22 16:00:31+00:00", + ), + to=datetime.datetime.fromisoformat( + "2025-07-22 16:00:31+00:00", + ), ) asyncio.run(main()) """ _response = await self._client_wrapper.httpx_client.request( - f"sites/{jsonable_encoder(site_id)}/accessgroups", + f"workspaces/{jsonable_encoder(workspace_id_or_slug)}/audit_logs", + base_url=self._client_wrapper.get_environment().base, method="GET", params={ - "offset": offset, "limit": limit, - "sort": sort, + "offset": offset, + "sortOrder": sort_order, + "eventType": event_type, + "from": serialize_datetime(from_) if from_ is not None else None, + "to": serialize_datetime(to) if to is not None else None, }, request_options=request_options, ) try: if 200 <= _response.status_code < 300: return typing.cast( - AccessGroupList, + WorkspaceAuditLogResponse, parse_obj_as( - type_=AccessGroupList, # type: ignore + type_=WorkspaceAuditLogResponse, # type: ignore object_=_response.json(), ), ) - if _response.status_code == 400: - raise BadRequestError( - typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ) - ) if _response.status_code == 401: raise UnauthorizedError( typing.cast( diff --git a/src/webflow/resources/workspaces/resources/audit_logs/types/__init__.py b/src/webflow/resources/workspaces/resources/audit_logs/types/__init__.py new file mode 100644 index 0000000..3decf29 --- /dev/null +++ b/src/webflow/resources/workspaces/resources/audit_logs/types/__init__.py @@ -0,0 +1,6 @@ +# This file was auto-generated by Fern from our API Definition. + +from .audit_logs_get_workspace_audit_logs_request_event_type import AuditLogsGetWorkspaceAuditLogsRequestEventType +from .audit_logs_get_workspace_audit_logs_request_sort_order import AuditLogsGetWorkspaceAuditLogsRequestSortOrder + +__all__ = ["AuditLogsGetWorkspaceAuditLogsRequestEventType", "AuditLogsGetWorkspaceAuditLogsRequestSortOrder"] diff --git a/src/webflow/resources/workspaces/resources/audit_logs/types/audit_logs_get_workspace_audit_logs_request_event_type.py b/src/webflow/resources/workspaces/resources/audit_logs/types/audit_logs_get_workspace_audit_logs_request_event_type.py new file mode 100644 index 0000000..08c3185 --- /dev/null +++ b/src/webflow/resources/workspaces/resources/audit_logs/types/audit_logs_get_workspace_audit_logs_request_event_type.py @@ -0,0 +1,15 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AuditLogsGetWorkspaceAuditLogsRequestEventType = typing.Union[ + typing.Literal[ + "user_access", + "custom_role", + "workspace_membership", + "site_membership", + "workspace_invitation", + "workspace_setting", + ], + typing.Any, +] diff --git a/src/webflow/resources/workspaces/resources/audit_logs/types/audit_logs_get_workspace_audit_logs_request_sort_order.py b/src/webflow/resources/workspaces/resources/audit_logs/types/audit_logs_get_workspace_audit_logs_request_sort_order.py new file mode 100644 index 0000000..dd90d5f --- /dev/null +++ b/src/webflow/resources/workspaces/resources/audit_logs/types/audit_logs_get_workspace_audit_logs_request_sort_order.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AuditLogsGetWorkspaceAuditLogsRequestSortOrder = typing.Union[typing.Literal["asc", "desc"], typing.Any] diff --git a/src/webflow/types/__init__.py b/src/webflow/types/__init__.py index 5b2d8c6..94afb21 100644 --- a/src/webflow/types/__init__.py +++ b/src/webflow/types/__init__.py @@ -1,7 +1,5 @@ # This file was auto-generated by Fern from our API Definition. -from .access_group import AccessGroup -from .access_group_list import AccessGroupList from .application import Application from .asset import Asset from .asset_folder import AssetFolder @@ -19,6 +17,8 @@ from .bulk_collection_item_field_data import BulkCollectionItemFieldData from .collection import Collection from .collection_item import CollectionItem +from .collection_item_changed import CollectionItemChanged +from .collection_item_created import CollectionItemCreated from .collection_item_field_data import CollectionItemFieldData from .collection_item_list import CollectionItemList from .collection_item_list_no_pagination import CollectionItemListNoPagination @@ -27,10 +27,31 @@ from .collection_item_patch_single_field_data import CollectionItemPatchSingleFieldData from .collection_item_post_single import CollectionItemPostSingle from .collection_item_post_single_field_data import CollectionItemPostSingleFieldData +from .collection_item_published import CollectionItemPublished +from .collection_item_removed import CollectionItemRemoved +from .collection_item_removed_payload import CollectionItemRemovedPayload +from .collection_item_removed_payload_field_data import CollectionItemRemovedPayloadFieldData +from .collection_item_unpublished import CollectionItemUnpublished +from .collection_item_unpublished_payload import CollectionItemUnpublishedPayload +from .collection_item_unpublished_payload_field_data import CollectionItemUnpublishedPayloadFieldData from .collection_item_with_id_input import CollectionItemWithIdInput from .collection_item_with_id_input_field_data import CollectionItemWithIdInputFieldData from .collection_list import CollectionList from .collection_list_array_item import CollectionListArrayItem +from .comment import Comment +from .comment_payload import CommentPayload +from .comment_payload_author import CommentPayloadAuthor +from .comment_payload_mentioned_users_item import CommentPayloadMentionedUsersItem +from .comment_reply import CommentReply +from .comment_reply_author import CommentReplyAuthor +from .comment_reply_list import CommentReplyList +from .comment_reply_list_pagination import CommentReplyListPagination +from .comment_reply_mentioned_users_item import CommentReplyMentionedUsersItem +from .comment_thread import CommentThread +from .comment_thread_author import CommentThreadAuthor +from .comment_thread_list import CommentThreadList +from .comment_thread_list_pagination import CommentThreadListPagination +from .comment_thread_mentioned_users_item import CommentThreadMentionedUsersItem from .component import Component from .component_dom import ComponentDom from .component_instance_node_property_overrides_write import ComponentInstanceNodePropertyOverridesWrite @@ -42,20 +63,28 @@ from .component_properties import ComponentProperties from .component_property import ComponentProperty from .component_property_type import ComponentPropertyType -from .conflict_error_body import ConflictErrorBody +from .conflict import Conflict from .custom_code_block import CustomCodeBlock from .custom_code_block_type import CustomCodeBlockType from .custom_code_hosted_response import CustomCodeHostedResponse from .custom_code_inline_response import CustomCodeInlineResponse +from .custom_role import CustomRole +from .custom_role_audit_log_item import CustomRoleAuditLogItem +from .custom_role_audit_log_item_event_sub_type import CustomRoleAuditLogItemEventSubType from .dom import Dom from .domain import Domain from .domains import Domains -from .duplicate_user_email import DuplicateUserEmail from .ecommerce_settings import EcommerceSettings from .error import Error from .error_code import ErrorCode from .field import Field +from .field_create import FieldCreate from .field_type import FieldType +from .field_validations import FieldValidations +from .field_validations_additional_properties import FieldValidationsAdditionalProperties +from .field_validations_additional_properties_additional_properties import ( + FieldValidationsAdditionalPropertiesAdditionalProperties, +) from .forbidden_error_body import ForbiddenErrorBody from .form import Form from .form_field import FormField @@ -65,23 +94,45 @@ from .form_response_settings import FormResponseSettings from .form_submission import FormSubmission from .form_submission_list import FormSubmissionList +from .form_submission_trigger import FormSubmissionTrigger +from .form_submission_trigger_payload import FormSubmissionTriggerPayload +from .form_submission_trigger_payload_schema_item import FormSubmissionTriggerPayloadSchemaItem +from .form_submission_trigger_payload_schema_item_field_type import FormSubmissionTriggerPayloadSchemaItemFieldType from .image_node import ImageNode from .image_node_image import ImageNodeImage from .invalid_domain import InvalidDomain from .invalid_scopes import InvalidScopes from .inventory_item import InventoryItem from .inventory_item_inventory_type import InventoryItemInventoryType +from .items_list_items_live_request_last_published import ItemsListItemsLiveRequestLastPublished +from .items_list_items_request_last_published import ItemsListItemsRequestLastPublished from .list_custom_code_blocks import ListCustomCodeBlocks from .locale import Locale from .locales import Locales +from .metadata import Metadata +from .metadata_options_item import MetadataOptionsItem +from .new_order import NewOrder from .no_domains import NoDomains -from .node import Node, Node_ComponentInstance, Node_Image, Node_Text +from .node import ( + Node, + Node_ComponentInstance, + Node_Image, + Node_SearchButton, + Node_Select, + Node_SubmitButton, + Node_Text, + Node_TextInput, +) from .not_enterprise_plan_site import NotEnterprisePlanSite from .not_enterprise_plan_workspace import NotEnterprisePlanWorkspace +from .option_field import OptionField from .order import Order from .order_address import OrderAddress from .order_address_japan_type import OrderAddressJapanType from .order_address_type import OrderAddressType +from .order_billing_address import OrderBillingAddress +from .order_billing_address_japan_type import OrderBillingAddressJapanType +from .order_billing_address_type import OrderBillingAddressType from .order_customer_info import OrderCustomerInfo from .order_dispute_last_status import OrderDisputeLastStatus from .order_download_files_item import OrderDownloadFilesItem @@ -92,15 +143,26 @@ from .order_purchased_item_variant_image import OrderPurchasedItemVariantImage from .order_purchased_item_variant_image_file import OrderPurchasedItemVariantImageFile from .order_purchased_item_variant_image_file_variants_item import OrderPurchasedItemVariantImageFileVariantsItem +from .order_shipping_address import OrderShippingAddress +from .order_shipping_address_japan_type import OrderShippingAddressJapanType +from .order_shipping_address_type import OrderShippingAddressType from .order_status import OrderStatus from .order_totals import OrderTotals from .order_totals_extras_item import OrderTotalsExtrasItem from .order_totals_extras_item_type import OrderTotalsExtrasItemType from .page import Page +from .page_created_webhook import PageCreatedWebhook +from .page_created_webhook_payload import PageCreatedWebhookPayload +from .page_deleted_webhook import PageDeletedWebhook +from .page_deleted_webhook_payload import PageDeletedWebhookPayload from .page_list import PageList +from .page_metadata_updated_webhook import PageMetadataUpdatedWebhook +from .page_metadata_updated_webhook_payload import PageMetadataUpdatedWebhookPayload from .page_open_graph import PageOpenGraph from .page_seo import PageSeo from .pagination import Pagination +from .payload import Payload +from .payload_field_data import PayloadFieldData from .paypal_details import PaypalDetails from .product import Product from .product_and_sk_us import ProductAndSkUs @@ -111,11 +173,26 @@ from .publish_status import PublishStatus from .redirect import Redirect from .redirects import Redirects +from .reference_field import ReferenceField +from .reference_field_metadata import ReferenceFieldMetadata +from .reference_field_type import ReferenceFieldType from .registered_script_list import RegisteredScriptList +from .robots import Robots +from .robots_rules_item import RobotsRulesItem from .script_apply import ScriptApply from .script_apply_list import ScriptApplyList from .script_apply_location import ScriptApplyLocation from .scripts import Scripts +from .search_button_node import SearchButtonNode +from .search_button_node_write import SearchButtonNodeWrite +from .select import Select +from .select_node import SelectNode +from .select_node_choices_item import SelectNodeChoicesItem +from .select_node_write_choices_item import SelectNodeWriteChoicesItem +from .setting_change import SettingChange +from .setting_change_audit_log_item import SettingChangeAuditLogItem +from .single_locale_created_payload import SingleLocaleCreatedPayload +from .single_locale_created_payload_field_data import SingleLocaleCreatedPayloadFieldData from .site import Site from .site_activity_log_item import SiteActivityLogItem from .site_activity_log_item_event import SiteActivityLogItemEvent @@ -123,9 +200,14 @@ from .site_activity_log_item_user import SiteActivityLogItemUser from .site_activity_log_response import SiteActivityLogResponse from .site_data_collection_type import SiteDataCollectionType +from .site_membership import SiteMembership +from .site_membership_audit_log_item import SiteMembershipAuditLogItem +from .site_membership_audit_log_item_event_sub_type import SiteMembershipAuditLogItemEventSubType from .site_plan import SitePlan from .site_plan_id import SitePlanId from .site_plan_name import SitePlanName +from .site_publish import SitePublish +from .site_publish_payload import SitePublishPayload from .sites import Sites from .sku import Sku from .sku_field_data import SkuFieldData @@ -139,31 +221,82 @@ from .sku_property_list import SkuPropertyList from .sku_property_list_enum_item import SkuPropertyListEnumItem from .sku_value_list import SkuValueList +from .static_field import StaticField +from .static_field_type import StaticFieldType from .stripe_card import StripeCard from .stripe_card_brand import StripeCardBrand from .stripe_card_expires import StripeCardExpires from .stripe_details import StripeDetails +from .submit_button_node import SubmitButtonNode +from .submit_button_node_write import SubmitButtonNodeWrite from .text import Text +from .text_input_node import TextInputNode +from .text_input_node_write import TextInputNodeWrite from .text_node import TextNode from .text_node_text import TextNodeText from .text_node_write import TextNodeWrite from .trigger_type import TriggerType -from .user import User -from .user_access_groups_item import UserAccessGroupsItem -from .user_access_groups_item_type import UserAccessGroupsItemType -from .user_data import UserData -from .user_data_data import UserDataData -from .user_limit_reached import UserLimitReached -from .user_list import UserList -from .user_status import UserStatus -from .users_not_enabled import UsersNotEnabled +from .updated_order import UpdatedOrder +from .user_access import UserAccess +from .user_access_audit_log_item import UserAccessAuditLogItem +from .user_access_audit_log_item_event_sub_type import UserAccessAuditLogItemEventSubType from .webhook import Webhook from .webhook_filter import WebhookFilter from .webhook_list import WebhookList +from .workspace_audit_log_item import ( + WorkspaceAuditLogItem, + WorkspaceAuditLogItem_CustomRole, + WorkspaceAuditLogItem_SiteMembership, + WorkspaceAuditLogItem_UserAccess, + WorkspaceAuditLogItem_WorkspaceInvitation, + WorkspaceAuditLogItem_WorkspaceMembership, + WorkspaceAuditLogItem_WorkspaceSetting, +) +from .workspace_audit_log_item_actor import WorkspaceAuditLogItemActor +from .workspace_audit_log_item_payload_setting_change_method import WorkspaceAuditLogItemPayloadSettingChangeMethod +from .workspace_audit_log_item_payload_site_membership_granular_access import ( + WorkspaceAuditLogItemPayloadSiteMembershipGranularAccess, +) +from .workspace_audit_log_item_payload_site_membership_method import WorkspaceAuditLogItemPayloadSiteMembershipMethod +from .workspace_audit_log_item_payload_site_membership_site import WorkspaceAuditLogItemPayloadSiteMembershipSite +from .workspace_audit_log_item_payload_site_membership_target_user import ( + WorkspaceAuditLogItemPayloadSiteMembershipTargetUser, +) +from .workspace_audit_log_item_payload_site_membership_user_type import ( + WorkspaceAuditLogItemPayloadSiteMembershipUserType, +) +from .workspace_audit_log_item_payload_user_access_method import WorkspaceAuditLogItemPayloadUserAccessMethod +from .workspace_audit_log_item_payload_workspace_invitation_method import ( + WorkspaceAuditLogItemPayloadWorkspaceInvitationMethod, +) +from .workspace_audit_log_item_payload_workspace_invitation_target_user import ( + WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUser, +) +from .workspace_audit_log_item_payload_workspace_invitation_target_users_item import ( + WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUsersItem, +) +from .workspace_audit_log_item_payload_workspace_invitation_user_type import ( + WorkspaceAuditLogItemPayloadWorkspaceInvitationUserType, +) +from .workspace_audit_log_item_payload_workspace_membership_method import ( + WorkspaceAuditLogItemPayloadWorkspaceMembershipMethod, +) +from .workspace_audit_log_item_payload_workspace_membership_target_user import ( + WorkspaceAuditLogItemPayloadWorkspaceMembershipTargetUser, +) +from .workspace_audit_log_item_payload_workspace_membership_user_type import ( + WorkspaceAuditLogItemPayloadWorkspaceMembershipUserType, +) +from .workspace_audit_log_item_workspace import WorkspaceAuditLogItemWorkspace +from .workspace_audit_log_response import WorkspaceAuditLogResponse +from .workspace_invitation import WorkspaceInvitation +from .workspace_invitation_audit_log_item import WorkspaceInvitationAuditLogItem +from .workspace_invitation_audit_log_item_event_sub_type import WorkspaceInvitationAuditLogItemEventSubType +from .workspace_membership import WorkspaceMembership +from .workspace_membership_audit_log_item import WorkspaceMembershipAuditLogItem +from .workspace_membership_audit_log_item_event_sub_type import WorkspaceMembershipAuditLogItemEventSubType __all__ = [ - "AccessGroup", - "AccessGroupList", "Application", "Asset", "AssetFolder", @@ -181,6 +314,8 @@ "BulkCollectionItemFieldData", "Collection", "CollectionItem", + "CollectionItemChanged", + "CollectionItemCreated", "CollectionItemFieldData", "CollectionItemList", "CollectionItemListNoPagination", @@ -189,10 +324,31 @@ "CollectionItemPatchSingleFieldData", "CollectionItemPostSingle", "CollectionItemPostSingleFieldData", + "CollectionItemPublished", + "CollectionItemRemoved", + "CollectionItemRemovedPayload", + "CollectionItemRemovedPayloadFieldData", + "CollectionItemUnpublished", + "CollectionItemUnpublishedPayload", + "CollectionItemUnpublishedPayloadFieldData", "CollectionItemWithIdInput", "CollectionItemWithIdInputFieldData", "CollectionList", "CollectionListArrayItem", + "Comment", + "CommentPayload", + "CommentPayloadAuthor", + "CommentPayloadMentionedUsersItem", + "CommentReply", + "CommentReplyAuthor", + "CommentReplyList", + "CommentReplyListPagination", + "CommentReplyMentionedUsersItem", + "CommentThread", + "CommentThreadAuthor", + "CommentThreadList", + "CommentThreadListPagination", + "CommentThreadMentionedUsersItem", "Component", "ComponentDom", "ComponentInstanceNodePropertyOverridesWrite", @@ -202,20 +358,26 @@ "ComponentProperties", "ComponentProperty", "ComponentPropertyType", - "ConflictErrorBody", + "Conflict", "CustomCodeBlock", "CustomCodeBlockType", "CustomCodeHostedResponse", "CustomCodeInlineResponse", + "CustomRole", + "CustomRoleAuditLogItem", + "CustomRoleAuditLogItemEventSubType", "Dom", "Domain", "Domains", - "DuplicateUserEmail", "EcommerceSettings", "Error", "ErrorCode", "Field", + "FieldCreate", "FieldType", + "FieldValidations", + "FieldValidationsAdditionalProperties", + "FieldValidationsAdditionalPropertiesAdditionalProperties", "ForbiddenErrorBody", "Form", "FormField", @@ -225,26 +387,43 @@ "FormResponseSettings", "FormSubmission", "FormSubmissionList", + "FormSubmissionTrigger", + "FormSubmissionTriggerPayload", + "FormSubmissionTriggerPayloadSchemaItem", + "FormSubmissionTriggerPayloadSchemaItemFieldType", "ImageNode", "ImageNodeImage", "InvalidDomain", "InvalidScopes", "InventoryItem", "InventoryItemInventoryType", + "ItemsListItemsLiveRequestLastPublished", + "ItemsListItemsRequestLastPublished", "ListCustomCodeBlocks", "Locale", "Locales", + "Metadata", + "MetadataOptionsItem", + "NewOrder", "NoDomains", "Node", "Node_ComponentInstance", "Node_Image", + "Node_SearchButton", + "Node_Select", + "Node_SubmitButton", "Node_Text", + "Node_TextInput", "NotEnterprisePlanSite", "NotEnterprisePlanWorkspace", + "OptionField", "Order", "OrderAddress", "OrderAddressJapanType", "OrderAddressType", + "OrderBillingAddress", + "OrderBillingAddressJapanType", + "OrderBillingAddressType", "OrderCustomerInfo", "OrderDisputeLastStatus", "OrderDownloadFilesItem", @@ -255,15 +434,26 @@ "OrderPurchasedItemVariantImage", "OrderPurchasedItemVariantImageFile", "OrderPurchasedItemVariantImageFileVariantsItem", + "OrderShippingAddress", + "OrderShippingAddressJapanType", + "OrderShippingAddressType", "OrderStatus", "OrderTotals", "OrderTotalsExtrasItem", "OrderTotalsExtrasItemType", "Page", + "PageCreatedWebhook", + "PageCreatedWebhookPayload", + "PageDeletedWebhook", + "PageDeletedWebhookPayload", "PageList", + "PageMetadataUpdatedWebhook", + "PageMetadataUpdatedWebhookPayload", "PageOpenGraph", "PageSeo", "Pagination", + "Payload", + "PayloadFieldData", "PaypalDetails", "Product", "ProductAndSkUs", @@ -274,11 +464,26 @@ "PublishStatus", "Redirect", "Redirects", + "ReferenceField", + "ReferenceFieldMetadata", + "ReferenceFieldType", "RegisteredScriptList", + "Robots", + "RobotsRulesItem", "ScriptApply", "ScriptApplyList", "ScriptApplyLocation", "Scripts", + "SearchButtonNode", + "SearchButtonNodeWrite", + "Select", + "SelectNode", + "SelectNodeChoicesItem", + "SelectNodeWriteChoicesItem", + "SettingChange", + "SettingChangeAuditLogItem", + "SingleLocaleCreatedPayload", + "SingleLocaleCreatedPayloadFieldData", "Site", "SiteActivityLogItem", "SiteActivityLogItemEvent", @@ -286,9 +491,14 @@ "SiteActivityLogItemUser", "SiteActivityLogResponse", "SiteDataCollectionType", + "SiteMembership", + "SiteMembershipAuditLogItem", + "SiteMembershipAuditLogItemEventSubType", "SitePlan", "SitePlanId", "SitePlanName", + "SitePublish", + "SitePublishPayload", "Sites", "Sku", "SkuFieldData", @@ -302,25 +512,56 @@ "SkuPropertyList", "SkuPropertyListEnumItem", "SkuValueList", + "StaticField", + "StaticFieldType", "StripeCard", "StripeCardBrand", "StripeCardExpires", "StripeDetails", + "SubmitButtonNode", + "SubmitButtonNodeWrite", "Text", + "TextInputNode", + "TextInputNodeWrite", "TextNode", "TextNodeText", "TextNodeWrite", "TriggerType", - "User", - "UserAccessGroupsItem", - "UserAccessGroupsItemType", - "UserData", - "UserDataData", - "UserLimitReached", - "UserList", - "UserStatus", - "UsersNotEnabled", + "UpdatedOrder", + "UserAccess", + "UserAccessAuditLogItem", + "UserAccessAuditLogItemEventSubType", "Webhook", "WebhookFilter", "WebhookList", + "WorkspaceAuditLogItem", + "WorkspaceAuditLogItemActor", + "WorkspaceAuditLogItemPayloadSettingChangeMethod", + "WorkspaceAuditLogItemPayloadSiteMembershipGranularAccess", + "WorkspaceAuditLogItemPayloadSiteMembershipMethod", + "WorkspaceAuditLogItemPayloadSiteMembershipSite", + "WorkspaceAuditLogItemPayloadSiteMembershipTargetUser", + "WorkspaceAuditLogItemPayloadSiteMembershipUserType", + "WorkspaceAuditLogItemPayloadUserAccessMethod", + "WorkspaceAuditLogItemPayloadWorkspaceInvitationMethod", + "WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUser", + "WorkspaceAuditLogItemPayloadWorkspaceInvitationTargetUsersItem", + "WorkspaceAuditLogItemPayloadWorkspaceInvitationUserType", + "WorkspaceAuditLogItemPayloadWorkspaceMembershipMethod", + "WorkspaceAuditLogItemPayloadWorkspaceMembershipTargetUser", + "WorkspaceAuditLogItemPayloadWorkspaceMembershipUserType", + "WorkspaceAuditLogItemWorkspace", + "WorkspaceAuditLogItem_CustomRole", + "WorkspaceAuditLogItem_SiteMembership", + "WorkspaceAuditLogItem_UserAccess", + "WorkspaceAuditLogItem_WorkspaceInvitation", + "WorkspaceAuditLogItem_WorkspaceMembership", + "WorkspaceAuditLogItem_WorkspaceSetting", + "WorkspaceAuditLogResponse", + "WorkspaceInvitation", + "WorkspaceInvitationAuditLogItem", + "WorkspaceInvitationAuditLogItemEventSubType", + "WorkspaceMembership", + "WorkspaceMembershipAuditLogItem", + "WorkspaceMembershipAuditLogItemEventSubType", ] diff --git a/src/webflow/types/access_group.py b/src/webflow/types/access_group.py deleted file mode 100644 index fa2a418..0000000 --- a/src/webflow/types/access_group.py +++ /dev/null @@ -1,49 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from ..core.pydantic_utilities import UniversalBaseModel -import typing -import pydantic -import typing_extensions -from ..core.serialization import FieldMetadata -import datetime as dt -from ..core.pydantic_utilities import IS_PYDANTIC_V2 - - -class AccessGroup(UniversalBaseModel): - id: typing.Optional[str] = pydantic.Field(default=None) - """ - Unique identifier for the Access Group - """ - - name: typing.Optional[str] = pydantic.Field(default=None) - """ - Name of the the Access Group - """ - - short_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="shortId")] = pydantic.Field( - default=None - ) - """ - Shortened unique identifier based on name, optimized for its use in the user’s JWT - """ - - slug: typing.Optional[str] = pydantic.Field(default=None) - """ - Shortened unique identifier based on name, optimized for human readability and public API use - """ - - created_on: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="createdOn")] = ( - pydantic.Field(default=None) - ) - """ - The date the Access Group was created - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/webflow/types/access_group_list.py b/src/webflow/types/access_group_list.py deleted file mode 100644 index 0d5e140..0000000 --- a/src/webflow/types/access_group_list.py +++ /dev/null @@ -1,51 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from ..core.pydantic_utilities import UniversalBaseModel -import typing -import pydantic -import typing_extensions -from .access_group import AccessGroup -from ..core.serialization import FieldMetadata -from ..core.pydantic_utilities import IS_PYDANTIC_V2 - - -class AccessGroupList(UniversalBaseModel): - """ - The list access groups results - """ - - count: typing.Optional[float] = pydantic.Field(default=None) - """ - Number of access groups returned - """ - - limit: typing.Optional[float] = pydantic.Field(default=None) - """ - The limit specified in the request - """ - - offset: typing.Optional[float] = pydantic.Field(default=None) - """ - The offset specified for pagination - """ - - total: typing.Optional[float] = pydantic.Field(default=None) - """ - Total number of access groups in the collection - """ - - access_groups: typing_extensions.Annotated[ - typing.Optional[typing.List[AccessGroup]], FieldMetadata(alias="accessGroups") - ] = pydantic.Field(default=None) - """ - List of Site Access Groups - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/webflow/types/application.py b/src/webflow/types/application.py index ac819f0..b11f910 100644 --- a/src/webflow/types/application.py +++ b/src/webflow/types/application.py @@ -1,5 +1,41 @@ # This file was auto-generated by Fern from our API Definition. +from ..core.pydantic_utilities import UniversalBaseModel import typing +import pydantic +import typing_extensions +from ..core.serialization import FieldMetadata +from ..core.pydantic_utilities import IS_PYDANTIC_V2 -Application = typing.Optional[typing.Any] + +class Application(UniversalBaseModel): + id: typing.Optional[str] = pydantic.Field(default=None) + """ + Unique identifier for the Application + """ + + description: typing.Optional[str] = pydantic.Field(default=None) + """ + Application description provided by the developer + """ + + homepage: typing.Optional[str] = pydantic.Field(default=None) + """ + Application homepage URL provided by the developer + """ + + display_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="displayName")] = ( + pydantic.Field(default=None) + ) + """ + Application name provided by the developer + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/webflow/types/asset.py b/src/webflow/types/asset.py index b67cefa..8ebad3b 100644 --- a/src/webflow/types/asset.py +++ b/src/webflow/types/asset.py @@ -11,6 +11,10 @@ class Asset(UniversalBaseModel): + """ + Asset details + """ + id: typing.Optional[str] = pydantic.Field(default=None) """ Unique identifier for this asset @@ -49,9 +53,7 @@ class Asset(UniversalBaseModel): Original file name at the time of upload """ - display_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="displayName")] = ( - pydantic.Field(default=None) - ) + display_name: typing_extensions.Annotated[str, FieldMetadata(alias="displayName")] = pydantic.Field() """ Display name of the asset """ @@ -70,7 +72,11 @@ class Asset(UniversalBaseModel): Date the asset metadata was created """ - variants: typing.Optional[typing.List[AssetVariant]] = None + variants: typing.List[AssetVariant] = pydantic.Field() + """ + A list of [asset variants](https://help.webflow.com/hc/en-us/articles/33961378697107-Responsive-images) created by Webflow to serve your site responsively. + """ + alt_text: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="altText")] = pydantic.Field( default=None ) diff --git a/src/webflow/types/asset_variant.py b/src/webflow/types/asset_variant.py index 5278667..0ad16f1 100644 --- a/src/webflow/types/asset_variant.py +++ b/src/webflow/types/asset_variant.py @@ -2,40 +2,38 @@ from ..core.pydantic_utilities import UniversalBaseModel import typing_extensions -import typing from ..core.serialization import FieldMetadata import pydantic +import typing from ..core.pydantic_utilities import IS_PYDANTIC_V2 class AssetVariant(UniversalBaseModel): - hosted_url: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="hostedUrl")] = pydantic.Field( - default=None - ) + """ + Asset variant details + """ + + hosted_url: typing_extensions.Annotated[str, FieldMetadata(alias="hostedUrl")] = pydantic.Field() """ URL of where the asset variant is hosted """ - original_file_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="originalFileName")] = ( - pydantic.Field(default=None) - ) + original_file_name: typing_extensions.Annotated[str, FieldMetadata(alias="originalFileName")] = pydantic.Field() """ Original file name of the variant """ - display_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="displayName")] = ( - pydantic.Field(default=None) - ) + display_name: typing_extensions.Annotated[str, FieldMetadata(alias="displayName")] = pydantic.Field() """ Display name of the variant """ - format: typing.Optional[str] = pydantic.Field(default=None) + format: str = pydantic.Field() """ format of the variant """ - width: typing.Optional[int] = pydantic.Field(default=None) + width: int = pydantic.Field() """ Width in pixels """ @@ -45,7 +43,7 @@ class AssetVariant(UniversalBaseModel): Height in pixels """ - quality: typing.Optional[int] = pydantic.Field(default=None) + quality: int = pydantic.Field() """ Value between 0 and 100 representing the image quality """ diff --git a/src/webflow/types/assets.py b/src/webflow/types/assets.py index 380b0de..bd5f8ea 100644 --- a/src/webflow/types/assets.py +++ b/src/webflow/types/assets.py @@ -3,6 +3,7 @@ from ..core.pydantic_utilities import UniversalBaseModel import typing from .asset import Asset +from .pagination import Pagination from ..core.pydantic_utilities import IS_PYDANTIC_V2 import pydantic @@ -13,6 +14,7 @@ class Assets(UniversalBaseModel): """ assets: typing.Optional[typing.List[Asset]] = None + pagination: typing.Optional[Pagination] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/webflow/types/bulk_collection_item.py b/src/webflow/types/bulk_collection_item.py index 4d17d13..de8e770 100644 --- a/src/webflow/types/bulk_collection_item.py +++ b/src/webflow/types/bulk_collection_item.py @@ -1,9 +1,9 @@ # This file was auto-generated by Fern from our API Definition. from ..core.pydantic_utilities import UniversalBaseModel +import typing import pydantic import typing_extensions -import typing from ..core.serialization import FieldMetadata from .bulk_collection_item_field_data import BulkCollectionItemFieldData from ..core.pydantic_utilities import IS_PYDANTIC_V2 @@ -14,7 +14,7 @@ class BulkCollectionItem(UniversalBaseModel): The fields that define the schema for a given Item are based on the Collection that Item belongs to. Beyond the user defined fields, there are a handful of additional fields that are automatically created for all items """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ Unique identifier for the Item """ diff --git a/src/webflow/types/collection.py b/src/webflow/types/collection.py index 81e0f90..561a535 100644 --- a/src/webflow/types/collection.py +++ b/src/webflow/types/collection.py @@ -3,8 +3,8 @@ from ..core.pydantic_utilities import UniversalBaseModel import pydantic import typing_extensions -import typing from ..core.serialization import FieldMetadata +import typing import datetime as dt from .field import Field from ..core.pydantic_utilities import IS_PYDANTIC_V2 @@ -20,16 +20,12 @@ class Collection(UniversalBaseModel): Unique identifier for a Collection """ - display_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="displayName")] = ( - pydantic.Field(default=None) - ) + display_name: typing_extensions.Annotated[str, FieldMetadata(alias="displayName")] = pydantic.Field() """ Name given to the Collection """ - singular_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="singularName")] = ( - pydantic.Field(default=None) - ) + singular_name: typing_extensions.Annotated[str, FieldMetadata(alias="singularName")] = pydantic.Field() """ The name of one Item in Collection (e.g. ”Blog Post” if the Collection is called “Blog Posts”) """ diff --git a/src/webflow/types/collection_item_changed.py b/src/webflow/types/collection_item_changed.py new file mode 100644 index 0000000..4484722 --- /dev/null +++ b/src/webflow/types/collection_item_changed.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +from ..core.pydantic_utilities import UniversalBaseModel +import typing_extensions +import typing +from ..core.serialization import FieldMetadata +import pydantic +from .single_locale_created_payload import SingleLocaleCreatedPayload +from ..core.pydantic_utilities import IS_PYDANTIC_V2 + + +class CollectionItemChanged(UniversalBaseModel): + """ + The Webhook payload for when a Collection Item is changed + """ + + trigger_type: typing_extensions.Annotated[ + typing.Literal["collection_item