Knak Assets API

The Assets API from Knak — 7 operation(s) for assets.

OpenAPI Specification

knak-assets-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  description: |
    # Overview
    Welcome to the developer documentation for the Knak Enterprise API.
    We provide a RESTful interface to key resources within the Knak platform to enable your own custom integration and automation workflows.
    This API will allow you to automate processes regarding user management within your Knak environment.
    You can download the formal definition of this public interface in OpenAPI 3 (formerly Swagger) format using the link above.

    ## Endpoint
    `https://enterprise.knak.io/api/published/v1`

    ## Additional APIs
    - [SCIM API Reference](https://enterprise.knak.io/docs/scim-api)

    ## Authentication
    All requests are authenticated using a Bearer token in the `Authorization` header:
    ```
    curl --location --request GET 'http://enterprise.knak.io/api/published/v1/emails' \
    --header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG...'
    ```
    There are two ways to obtain tokens:
    ### 1 - API Key
    A user generates a non-expiring token through the Enterprise UI, via the [API Access menu](https://enterprise.knak.io/account/api-access). This is generally only recommended for testing and development, or if the Oauth2 flow is not applicable to your particular use case.

    ### 2 - OAuth2 via Authorization Code Grant Flow
    This is the **recommended** method for users to allow your application access to their data in Knak. You can manage your own OAuth2 applications in Knak [**here**](http://enterprise.knak.io/account/oauth-applications). Please contact support to enable this feature if unauthorized, or if you need a specific developer account set up for Knak.
    - **Authorization URL**
        - `https://enterprise.knak.io/oauth/authorize`
    - **Token URL**
        - `https://enterprise.knak.io/oauth/token`

    Creating an OAuth2 application will provide you with a *client_id*, *client_secret* and a *redirect_uri* of your choosing. Users can then authorize your application to access their Knak account by being directed to the Authorization URL:

    ```
    http://enterprise.knak.io/oauth/authorize?client_id=<your client ID>&redirect_uri=http://your.redirect.url/callback&response_type=code&state=xyzABC123
    ```

    | Query Parameter | Description |
    | ----------------| ----------- |
    | client_id       | **(Required)** The client ID for your application|
    | redirect_uri    | **(Required)** The url the client will be redirected to. HTTPS required. Must match the url specified in your OAuth2 application|
    | response_type   | **(Required)** Only a value of `code` is currently supported|
    | state           | (Optional) This value will be included as part of the redirect response. Your OAuth2 client library most likely uses this parameter to prevent CSRF attacks|

    The user will be redirected to your `redirect_uri` with the authorization code included as the `code` query parameter:
    ```http
    HTTP/1.1 302 Found
    Location: https://your.redirect.url/callback?code=AUTHORIZATION_CODE&state=xyzABC123
    ```
    You can then use this code to request a `(access_token, refresh_token)` pair from the Token URL:
    ```http
    POST /oauth/token HTTP/1.1
    Host: enterprise.knak.io
    Accept: application/json
    Authorization: Bearer ...
    Content-Type: application/x-www-form-urlencoded
    grant_type=authorization_code&client_id=<client_id>&client_secret=<client_secret>&redirect_uri=<redirect_uri>&code=AUTHORIZATION_CODE
    ```
    ## Errors
    Errors in requests made to the API can be viewed directly from the response code that is returned.

    Below are a list of the common error responses returned and an explanation of what they mean.

    | Code | Reason |Description |
    | ----------------| ----------- | ----------- |
    | **400**      | **Bad Request** | Request is malformed or invalid. |
    | **401**      | **Unauthenticated** | Need to be signed in with a proper account to make this request. |
    | **403**    | **Forbidden** | The request cannot be completed because the account that is being used does not have sufficient permissions to perform the action in question. |
    | **404**  | **Not Found** | The requested resource could not be found. Verify that the resource you are looking for exists and that you are using the proper key to search for it. |

    ## Pagination
    Our API supports pagination, allowing you to navigate through large sets of data efficiently. This is particularly useful for endpoints that can return a lot of data, such as listings of users, assets, or other entities. To manage the amount of data returned, we use two query parameters: `page` and `per_page`.

    ### Parameters
    page (Integer, optional): This parameter specifies the page number in the results set. Each page contains a subset of the total data based on the per_page value. The default value is 1 if not specified.

    per_page (Integer, optional): This parameter controls the number of items returned per page. It allows you to specify the page size, i.e., how many items you want to be included in each page of results. The default value is 10, and the maximum allowable value is 100.

    ### Defaults and Limits
    If neither page nor per_page is specified, the API will return the first page with the default size of 10 items.
    The per_page parameter defaults to 10 but can be set to any integer up to a maximum of 100. Requests for more than 100 items per page will be capped at 100.

    ## Filtering
    Our API supports filtering on specific fields of resources for GET requests. This allows clients to retrieve a subset of records based on certain criteria. Supported filters will be listed in each endpoint.

    ### Parameters
    filter[field_name]:To apply filters, add a filter query parameter to your GET request, followed by the field name you wish to filter on.
    Each filter can have one of the following types:

    #### Exact
    This filter type is used to match the exact value of a field.

    #### Partial
    This filter type will return all matches that contain the specified value.

    #### Scope
    This filter type is used to filtered on a static list of values. Supported items will be listed in each endpoint.

    ## Sorting
    Our API provides sorting functionality, allowing clients to order the results of a GET request based on specified fields. Sorting makes it easier to organize and navigate through lists of records.

    ### Parameters
    sort (string, optional): To apply sorting, use the sort query parameter followed by the field name you wish to sort by:

    - updated_at: Sorts records by the last update timestamp.

    - created_at: Sorts records by the creation timestamp.

    ## Webhook Setup
    Webhooks are a way to notify your application when a specific event occurs in your Knak environment. When the event occurs, Knak sends an HTTP POST request to the webhook's configured URL. You can use webhooks to trigger custom workflows, send notifications, or update external systems based on events that occur in Knak.
    For information on how to create and manage webhooks, please visit the [Knak Custom Integration Setup](https://help.knak.io/en/articles/7950399-knak-custom-integration-setup) page in the Knak Help Center, and the events section below.

    ## Retry Policy
    Webhooks will be sent out up to a maximum of three times, with a delay of 60 seconds between each request, until a Successful response status is returned.

    ## Verifying Webhook Signatures
    Webhooks are signed using a SHA-256 HMAC with the secret generated in Knak. The signature is included in the `knak-signature` header of the request. You can use this signature to verify that the request was sent by Knak, and not a third party.

    Before you can verify the signature, you will need to obtain the secret from Knak. You can do this by navigating to the [Webhooks](https://enterprise.knak.io/account/webhooks) page in the Enterprise UI. Select the webhook you want to obtain the secret for, and click the reveal icon next to the secret. In the code sample below we assume that the secret is stored in an environment variable called `WEBHOOK_SECRET`.

    You can perform this verification in any language that supports HMAC-SHA256. You provide the request body and secret as input to the HMAC-SHA256 algorithm, and then compare the output to the signature provided in the request header.

    View the sample code below for an example of how to verify the signature using Node and express.js.
    ```javascript
    const crypto = require('crypto');
    const express = require("express");
    const app = express();

    app.post("/sync-requested", express.raw({type: 'application/json'}), (req, res) => {
        try {
            // Get the knak-signature header from the request
            const signature = req.headers['knak-signature'];

            // Generate the hash value from the request body
            const payload = req.body.toString();
            const secret = process.env.WEBHOOK_SECRET;
            const hmac = crypto.createHmac('sha256', secret).update(payload);

            // Generate hexidecimal hash value
            const calculatedHash = hmac.digest('hex');

            // Compare the calculated hash to the knak-signature header
            if (crypto.timingSafeEqual(Buffer.from(calculatedHash), Buffer.from(signature))) {
                // continue processing the request
                res.send("Payload is authentic");
            } else {
                // reject the request
                res.send("Payload has been tampered with");
            }
        } catch (err) {
            res.status(500).send("An error occurred");
        }
    });
    ```
  version: V1
  title: Knak Enterprise API — Assets
  x-logo:
    url: https://s3.amazonaws.com/assets.knak.io/img/Knak-Logo-Medium.png
servers:
- url: https://enterprise.knak.io/api/published/v1
  description: production
tags:
- name: Assets
paths:
  /assets:
    get:
      description: Retrieve all [assets](#tag/asset_model)  in organization.
      summary: List all assets
      parameters:
      - name: page
        in: query
        required: false
        description: Page number
        example: 1
        schema:
          type: integer
      - name: per_page
        in: query
        required: false
        description: Number of items per page
        example: 10
        schema:
          type: integer
      - name: filter[parent_asset_id]
        in: query
        required: false
        description: Filter assets by parent asset ID. Exact match filter.
        example: 609ca344d1b1b
        schema:
          type: string
      tags:
      - Assets
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetList'
        '401':
          description: Unauthenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                errors:
                - title: Unauthenticated.
                  detail: Authenticate before continuing.
        '403':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                errors:
                - title: Forbidden.
                  detail: This user is not authorized to perform this action. Please adjust permissions
                    before continuing.
    post:
      description: Create an [asset](#tag/asset_model). Can either be a email or landing page, and must
        be associated with a campaign.
      summary: Create an asset
      tags:
      - Assets
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - name
              - type
              - campaign_id
              properties:
                name:
                  type: string
                  example: test
                type:
                  type: string
                  enum:
                  - email
                  - landing
                  maxLength: 13
                  example: email
                campaign_id:
                  type: string
                  maxLength: 13
                  example: 609d7ce223411
                from_name:
                  type: string
                  nullable: true
                  maxLength: 191
                  example: Sender
                from_email:
                  type: string
                  format: email
                  nullable: true
                  maxLength: 191
                  example: email@knak.com
                reply_email:
                  type: string
                  format: email
                  nullable: true
                  maxLength: 191
                  example: reply_email@knak.com
                subject:
                  type: string
                  nullable: true
                  maxLength: 500
                  example: Email Subject
                preview_text:
                  type: string
                  nullable: true
                  maxLength: 500
                  example: This is the preview text.
                theme_id:
                  type: string
                  nullable: true
                  maxLength: 13
                  example: 609d7ce223411
                custom_fields:
                  type: array
                  items:
                    type: object
                    properties:
                      name:
                        type: string
                        example: custom_field_key_1
                      value:
                        type: string
                        example: field value 1
                tags:
                  type: array
                  items:
                    type: string
                    example: tag 1
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetItem'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                errors:
                - title: Validation error for name.
                  detail: The name field is required.
        '401':
          description: Unauthenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                errors:
                - title: Unauthenticated.
                  detail: Authenticate before continuing.
        '403':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                errors:
                - title: Forbidden.
                  detail: This user is not authorized to perform this action. Please adjust permissions
                    before continuing.
  /assets/generate:
    post:
      description: |-
        Generate an AI-powered email [asset](#tag/asset_model) from a text prompt. The asset is created immediately and returned in the response with `ai_generation_status: started`. AI content generation runs asynchronously in the background. Poll `GET /assets/{asset_id}` to check when `ai_generation_status` changes to `completed` or `failed`.

        The asset must be associated with a campaign (asset folder). The brand is automatically resolved from the campaign.
      summary: Generate an AI email asset
      tags:
      - Assets
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - prompt
              - type
              - campaign_id
              properties:
                prompt:
                  type: string
                  description: Text instructions describing the email to generate. This is the main input
                    for the AI generation.
                  example: Create a promotional email for our spring sale with 20% off all items
                type:
                  type: string
                  enum:
                  - email
                  description: The type of asset to generate. Currently only `email` is supported.
                  example: email
                campaign_id:
                  type: string
                  maxLength: 13
                  description: The ID of the campaign (asset folder) where the asset will be created.
                    The brand is automatically resolved from the campaign.
                  example: 609d7ce223411
                name:
                  type: string
                  nullable: true
                  maxLength: 512
                  description: Optional name for the asset. If not provided, a name may be auto-generated.
                  example: Spring Sale Promo
                theme_id:
                  type: string
                  nullable: true
                  maxLength: 13
                  description: Optional theme ID to base the generated email on. Must belong to your company.
                  example: 609d7ce223411
                subject:
                  type: string
                  nullable: true
                  maxLength: 191
                  description: Optional subject line for the email. If not provided, the AI will generate
                    a subject line automatically.
                  example: Spring Sale - 20% Off Everything
                from_name:
                  type: string
                  nullable: true
                  maxLength: 191
                  description: Sender name for the email.
                  example: Marketing Team
                from_email:
                  type: string
                  nullable: true
                  maxLength: 191
                  description: Sender email address.
                  example: marketing@example.com
                reply_email:
                  type: string
                  nullable: true
                  maxLength: 191
                  description: Reply-to email address.
                  example: replies@example.com
                tags:
                  type: array
                  nullable: true
                  items:
                    type: string
                  description: Tags to apply to the generated asset.
                  example:
                  - spring-sale
                  - promo
                images:
                  type: array
                  nullable: true
                  maxItems: 10
                  description: Images to provide as context for AI generation. Maximum 10 images.
                  items:
                    type: object
                    required:
                    - url
                    - filename
                    properties:
                      url:
                        type: string
                        format: uri
                        description: Publicly accessible URL of the image.
                        example: https://example.com/images/hero.png
                      filename:
                        type: string
                        description: Filename for the image.
                        example: hero.png
                files:
                  type: array
                  nullable: true
                  maxItems: 2
                  description: Files (e.g. PDFs) to provide as context for AI generation. Maximum 2 files.
                  items:
                    type: object
                    required:
                    - url
                    - filename
                    properties:
                      url:
                        type: string
                        format: uri
                        description: Publicly accessible URL of the file.
                        example: https://example.com/files/brand-guide.pdf
                      filename:
                        type: string
                        description: Filename for the file.
                        example: brand-guide.pdf
                asset_id:
                  type: string
                  nullable: true
                  maxLength: 13
                  description: Optional. When provided, overwrites the target email asset's content with
                    a new version instead of creating a new asset. Must reference an email asset in your
                    company, and you must have save permission on that asset. `campaign_id` is still required
                    and its brand is used for the regenerated content.
                  example: 609d7ce223411
                module_ids:
                  type: array
                  nullable: true
                  maxItems: 10
                  description: Optional module IDs to use as building blocks for the generated email.
                    Each module must belong to your company. Only the latest published version of each
                    module is used; modules without a published version are ignored. Maximum 10 modules.
                  items:
                    type: string
                    maxLength: 13
                  example:
                  - 63eff78889f21
      responses:
        '200':
          description: Asset created successfully. AI content generation is running asynchronously. Poll
            GET /assets/{asset_id} to check generation status.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetItem'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                errors:
                - title: Validation error for prompt.
                  detail: A prompt is required.
                - title: Validation error for asset_id.
                  detail: The specified asset does not exist or is not an email asset in your company.
                - title: Validation error for module_ids.
                  detail: One or more of the specified modules do not exist in your company.
        '401':
          description: Unauthenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                errors:
                - title: Unauthenticated.
                  detail: Authenticate before continuing.
        '403':
          description: Forbidden - AI generation is not enabled for this account, or (when `asset_id`
            is provided) the caller does not have save permission on the target asset.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                errors:
                - title: Forbidden.
                  detail: This user is not authorized to perform this action. Please adjust permissions
                    before continuing.
        '429':
          description: Too Many Requests - Rate limit exceeded (5 requests per minute)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                errors:
                - title: Too Many Requests.
                  detail: You have exceeded the rate limit. Please try again later.
  /assets/{asset_id}:
    get:
      description: Retrieve a specific [asset](#tag/asset_model)'s information, given their asset ID.
      summary: Retrieve specific asset
      parameters:
      - in: path
        required: true
        name: asset_id
        description: ID of asset
        example: 609d7ce223411
        schema:
          type: string
      tags:
      - Assets
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetItem'
        '401':
          description: Unauthenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                errors:
                - title: Unauthenticated.
                  detail: Authenticate before continuing.
        '403':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                errors:
                - title: Forbidden.
                  detail: This user is not authorized to perform this action. Please adjust permissions
                    before continuing.
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                errors:
                - title: Resource Not Found.
                  detail: Could not find the email you were looking for.
  /assets/{asset_id}/content:
    get:
      description: Retrieve a specific asset's html content. Returns a similar response to the /assets/
        GET endpoint, but includes field 'html' in the response.
      summary: Retrieve specific asset content
      parameters:
      - name: asset_id
        in: path
        required: true
        description: ID of asset
        example: 609d7ce223411
        schema:
          type: string
      - name: platform
        in: query
        required: false
        description: name of platform
        example: marketo
        schema:
          type: string
      tags:
      - Assets
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetContent'
        '401':
          description: Unauthenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Response'
              example:
                message: Authenticate before continuing.
        '403':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Response'
              example:
                message: This user is not authorized to perform this action. Please adjust permissions
                  before continuing.
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Response'
              example:
                message: Resource not found.
  /assets/{asset_id}/preview:
    get:
      description: |-
        Retrieve a rendered preview of a specific asset. The returned `url` is publicly accessible without authentication. A 202 response with `url` set to null means the preview is still being generated; the client should poll this endpoint again until a 200 is returned.

        Use the `client` and `details` query parameters to control how the preview is rendered. `client` applies to both the `png` and `pdf` formats. `details` only takes effect for `format=pdf` with `client=desktop`; it is ignored for `png` and for `pdf` with `client=mobile`.
      summary: Retrieve specific asset preview
      parameters:
      - name: asset_id
        in: path
        required: true
        description: ID of asset
        example: 609d7ce223411
        schema:
          type: string
      - name: format
        in: query
        required: false
        description: Preview format
        example: png
        schema:
          type: string
          enum:
          - png
          - pdf
          default: png
      - name: client
        in: query
        required: false
        description: The client to render the preview for. Applies to both `png` and `pdf` formats.
        example: desktop
        schema:
          type: string
          enum:
          - desktop
          - mobile
          default: desktop
      - name: details
        in: query
        required: false
        description: Whether to include the email details header in the preview. Only takes effect for
          `format=pdf` with `client=desktop`, where `false` omits the details header. Ignored for `png`
          (any client) and for `pdf` with `client=mobile`, where the details header is always included.
          Defaults to `true`.
        example: true
        schema:
          type: boolean
          default: true
      tags:
      - Assets
      responses:
        '200':
          description: Preview is ready. The `url` is populated and publicly accessible.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetPreview'
        '202':
          description: Preview is still being generated. The `url` is null; poll again until a 200 is
            returned.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetPreview'
              example:
                data:
                  id: 609d7ce223411
                  format: png
                  client: desktop
                  details: true
                  url: null
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                errors:
                - title: Validation error for format.
                  detail: The format must be either png or pdf.
        '401':
          description: Unauthenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                errors:
                - title: Unauthenticated.
                  detail: Authenticate before continuing.
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                errors:
                - title: Forbidden.
                  detail: This user is not authorized to perform this action. Please adjust permissions
                    before continuing.
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                errors:
                - title: Not Found.
                  detail: Could not find the email you were looking for.
  /assets/{asset_id}/custom-fields:
    get:
      description: Retrieve the custom fields that are defined on a specific asset.
      summary: Retrieve custom fields of an asset
      parameters:
      - name: asset_id
        in: path
        required: true
        description: ID of asset
        example: 609d7ce223411
        schema:
          type: string
      tags:
      - Assets
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetCustomFields'
        '401':
          description: Unauthenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Response'
              example:
                message: Authenticate before continuing.
        '403':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Response'
              example:
                message: This user is not authorized to perform this action. Please adjust permissions
                  before continuing.
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Response'
              example:
                message: Resource not found.
    patch:
      description: Edit the custom field values of a specific asset.
      summary: Edit custom fields of an asset
      parameters:
      - na

# --- truncated at 32 KB (55 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/knak/refs/heads/main/openapi/knak-assets-api-openapi.yml