More powerful page endpoints in the Coda API

You can do many things with the Coda API, but for a long time there was one part of a Coda doc that was almost completely inaccessible: pages. While it did provide some basic metadata about the pages in a doc, the content of those pages was off limits.

Why? Because pages are complicated! Trying to come up with a stable API representation for a rich and quickly evolving document model is not an easy task.

However we heard from our developer community pretty consistently over the years that you want some way to work with page content, and over the last few months we’ve rolled out some changes that we think you’ll like. Specifically:

  • Page content can now be read or written in either HTML or markdown format.
  • When updating a page, you can replace the page content or append to it.
  • We’ve added new endpoints for creating pages and for exporting pages.

Creating a page

To create a page, send a POST request to the endpoint https://coda.io/apis/v1/docs/{docId}/pages. You can optionally include metadata like the page name, subtitle, icon, cover image, and parent page.

You can also set the initial content of the page at the same time, specified as HTML or Markdown, or a URL to use as the source of an Embed page. (Note that a page cannot be toggled between a regular canvas page and an Embed page after the fact, this can only be set at creation time.)

Here’s an example request body which creates a new page, specifying all available attributes, including HTML content:

{
  "name": "Launch Status",
  "subtitle": "See the status of launch-related tasks.",
  "iconName": "rocket",
  "imageUrl": "https://example.com/image.jpg",
  "parentPageId": "canvas-tuVwxYz",
  "pageContent": {
    "type": "canvas",
    "canvasContent": {
      "format": "html",
      "content": "<p><b>This</b> is rich text</p>"
    }
  }
}

Updating a page

To update a page, send a PUT request to https://coda.io/apis/v1/docs/{docId}/pages/{pageIdOrName}. You can modify much of the metadata of the page, and any fields you omit will remain unchanged.

For regular canvas pages you can also update the content of the page, either replacing the existing page content or appending to it. Insertion of content at arbitrary points in the page is not currently supported.

Here is a sample request body which updates the page name and appends new content to the end of the page using Markdown:

{
  "name": "New Page Name",
  "contentUpdate": {
    "insertionMode": "append",
    "canvasContent": {
      "format": "markdown",
      "content": "# New Section\n\nThis is a new section of the page."
    }
  }
}

Exporting a page

To read the content of a page you need to export it to HTML or markdown. Because pages can get very large, exporting content must be queued up and processed asynchronously. Exporting the page content involves the following steps:

  1. Send a POST request to https://coda.io/apis/v1/docs/{docId}/pages/{pageIdOrName}/export to begin a new export, making sure to specify the desired output format (”html” or ”markdown”).
    The response will contain the id of the export and an href where you can fetch information about it.
  2. Make a GET request to the href URL to check the status of the export. Continue to poll this endpoint until the status is “complete”.
    A completed export will include a downloadLink field which is the URL of a temporary file that contains the exported content.
  3. Make a request to the URL specified in the downloadLink to retrieve the exported page content.

Be aware

  • HTML and markdown can’t perfectly represent all of the features of a Coda doc, so a round trip in either format may lose some information. These endpoints are best used for import or export scenarios, not page editing.
  • While the exported file remains live for a few days, the downloadLink returned by the API expires after only a few minutes. To get a fresh URL to your export simply make another request to retrieve the export status.
  • If you begin a new export and then immediately check it’s status you might get a 404 Not Found error response. This is because our backend hasn’t caught up just yet. Simply wait a second and retry.

We hope these new endpoints simplify your workflows and open up new use cases!

18 Likes

So stoked

Updates to the doc explorer pack here we come.

2 Likes

@JonathanGoldman,

well done to you and your team, a much needed improvement indeed!

can this allow me to create a full-page-embed page and set the URL and “force:true” parameters?

max

1 Like

Amazing news! Glad to see the API getting some love :love_you_gesture:

1 Like

I am BEYOND STOKED for this update. So excited to use this!!

Nice, gonna update the Add Page pack to allow page duplication (to the extent that this new Import/Export capability allows)

1 Like

@JonathanGoldman how would we create a page using a template?

Hi @Agile_Dynamics, you can indeed use to this to create a full-page embed. We’ll follow up this week with the ability to specify “Compatibility” mode when creating the embed, good idea.

Hi @briandtr do you mean something like specifying the doc id/page id of a template and having that inserted as the initial content? That isn’t supported today but is a good feature request.

1 Like

Hi,

Would somebody be able to advise on how to retrieve the parentpageid?

I can’t find anything related to pageid/parentpageid in the documentation. :frowning:

Many thanks!

yep - that would be epic

This is one way to do that:
thisDocument.ObjectLink().split(“_d”).last()

image

2 Likes

Hi,

Thank you very much for your response.

The suggested formula seems to be returning the Doc ID. Do you happen to know if the formula can be extended to retrieve the pageId instead?

Hi @Savia ! If you go to https://coda.io/account, at the very bottom under Labs, there is an option to turn on Developer Mode, which will give you handy menu options for getting entity ids that you may want to use with the API. Once you enable that, in the three-dot menu for each page, you’ll be able to directly copy the page id.

3 Likes

Hi Jonathan and community,

I’m trying to use this feature to read content of Coda pages in a custom GPT using their OpenAPI schema implementation, but I’m having some problems. I’ll leave the schema along with a summary, maybe someone can help me out understanding why I’m having trouble with access to the exported content.

Issue Summary:

We are experiencing issues with the Coda API while trying to export page content. The export initiation works fine, but when checking the export status, it consistently returns a 404 “Not Found” error. Below are the details of the process and the error encountered.

Steps to Reproduce:

  1. List Pages: Successfully listed pages in the document.
  • Doc ID: pB_XX_QiAv
  • Page ID: canvas-y9wBS-aw7Q
  • Page Name: “Sub first”
  1. Initiate Export:
  • Endpoint: POST /docs/{docId}/pages/{pageIdOrName}/export
  • Request:

json

Copiar cĂłdigo

{
  "docId": "pB_XX_QiAv",
  "pageIdOrName": "canvas-y9wBS-aw7Q",
  "outputFormat": "html"
}
  • Response:

json

Copiar cĂłdigo

{
  "id": "bd5635a2-4bfa-4bdc-9f21-37bd872e4502",
  "status": "inProgress",
  "href": "https://coda.io/apis/v1/docs/pB_XX_QiAv/pages/canvas-y9wBS-aw7Q/export/bd5635a2-4bfa-4bdc-9f21-37bd872e4502"
}
  1. Check Export Status:
  • Endpoint: GET /exports/{exportId}
  • Request:

json

Copiar cĂłdigo

{
  "exportId": "bd5635a2-4bfa-4bdc-9f21-37bd872e4502"
}
  • Response:

json

Copiar cĂłdigo

{
  "statusCode": 404,
  "statusMessage": "Not Found",
  "message": "Not Found"
}

Issue Details:

  • The export process initiates correctly, returning an export ID.
  • When polling the export status using the provided export ID, the response is consistently a 404 error indicating the export ID is not found.
  • Manual download from the provided link in the export initiation response works successfully, confirming that the export itself completes but the status check via the API fails.

Additional Context:

  • We are in the process of creating a custom GPT using Coda’s API documentation.
  • As a non-developer, I am using GPT to assist me with API interactions and implementation.
  • This issue is a critical blocker in our workflow, and any assistance to resolve this would be greatly appreciated.

Attempts to Resolve:

  • Repeated the export initiation and status check multiple times.
  • Verified the correctness of the docId, pageIdOrName, and exportId.
  • Ensured adequate delay between initiating the export and polling the status.

Request for Support:

Please assist in identifying the potential cause of the 404 error when checking the export status. Any insights or further steps to troubleshoot this issue would be greatly appreciated. Additionally, since manual download works, the issue seems to be specific to the implementation of the getExportStatus endpoint.

Thank you for your assistance.

Schema used:

openapi: 3.1.0
info:
  title: Coda API
  description: API for interacting with Coda documents, including listing pages, exporting page content, and updating page content.
  version: 1.0.0
servers:
  - url: https://coda.io/apis/v1
    description: Coda API Server
paths:
  /docs/{docId}/pages:
    get:
      operationId: listPages
      summary: List pages in a document
      parameters:
        - name: docId
          in: path
          required: true
          schema:
            type: string
            example: "yourDocId"
      responses:
        '200':
          description: List of pages in the document
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        name:
                          type: string
                        type:
                          type: string
                        parentPageId:
                          type: string
  /docs/{docId}/pages/{pageIdOrName}/export:
    post:
      operationId: exportPage
      summary: Export page content
      parameters:
        - name: docId
          in: path
          required: true
          schema:
            type: string
            example: "yourDocId"
        - name: pageIdOrName
          in: path
          required: true
          schema:
            type: string
            example: "yourPageIdOrName"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                outputFormat:
                  type: string
                  enum:
                    - html
                    - markdown
                  example: "html"
      responses:
        '202':
          description: Export request accepted
          content:
            application/json:
              schema:
                type: object
                properties:
                  exportId:
                    type: string
                  href:
                    type: string
  /exports/{exportId}:
    get:
      operationId: getExportStatus
      summary: Get export status
      parameters:
        - name: exportId
          in: path
          required: true
          schema:
            type: string
            example: "yourExportId"
      responses:
        '200':
          description: Export status information
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                  downloadLink:
                    type: string
        '404':
          description: Export not found or not ready yet
  /docs/{docId}/pages/{pageIdOrName}:
    put:
      operationId: updatePage
      summary: Update page content
      parameters:
        - name: docId
          in: path
          required: true
          schema:
            type: string
            example: "yourDocId"
        - name: pageIdOrName
          in: path
          required: true
          schema:
            type: string
            example: "yourPageIdOrName"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                contentUpdate:
                  type: object
                  properties:
                    insertionMode:
                      type: string
                      enum:
                        - replace
                        - append
                    canvasContent:
                      type: object
                      properties:
                        format:
                          type: string
                          enum:
                            - html
                            - markdown
                        content:
                          type: string
      responses:
        '200':
          description: Page updated successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  name:
                    type: string
                  parentPageId:
                    type: string

We need this. Is it coming?