Saw this Quick Start guide on Canva's developer portal that walks you through creating a content extension for Canva's users. It uses Node.js and Express.js as the server backend. I wanted to replicate this example using Python and Flask as the server.

My Flask server listening and responding to POST request from Canvac

What is a content extension?

This is how Canva describes it:

A content extension allows you to import third-party content, such as photos and illustrations, into Canva. Users can access this content via the side panel and add it to their designs.

How content extensions work

  1. You visit the Canva Developer Portal and create an app.
  2. You provide the endpoint/base URL for your app. This is the endpoint where Canva will send a POST request. One thing to note is that Canva adds "/content/resources/find" to the base URL, so your service should be answering the POST request at - your-service.com/any-custom-route/content/resources/find
  3. Your service should then return the content in the following format. The content that your service responds with is used to render the content in the side panel.
{
	"type": "SUCCESS",
    "resources":[
		{
            "contentType": "image/jpeg",
            "id": "0",
            "name": "Alejandro Escamilla",
            "thumbnail": {
                "url": "https://picsum.photos/id/0/5616/3744"
            },
            "type": "IMAGE",
            "url": "https://picsum.photos/id/0/5616/3744"
        },
        {
            "contentType": "image/jpeg",
            "id": "1",
            "name": "Alejandro Escamilla",
            "thumbnail": {
                "url": "https://picsum.photos/id/1/5616/3744"
            },
            "type": "IMAGE",
            "url": "https://picsum.photos/id/1/5616/3744"
        }
       ]
}

Step 1: Build the backend service

If you already have a service that has the content, you can skip this step, and just make sure that it returns data in the format Canva is expecting (see above).

Here's the code you can use to fire up a Flask server -

#inside main.py

from flask import Flask, request, render_template
import requests 
import json

app = Flask(__name__)
app.config["DEBUG"] = True

# Define the route which will receive the POST request from Canva
@app.route("/canva/content/resources/find", methods=['POST'])
def get_content():
	# Gather the content you want to send back. Here we are using picsum.photos, a placeholder API for pictures.
    url = "https://picsum.photos/v2/list"
    r = requests.get(url)
    results = json.loads(r. text)

    resources = []
	
    # Loop through the results received from picsum API, and prepare the content in the format expected by Canva.
    for resource in results:
        content = {
            "type": "IMAGE",
            "id": resource["id"],
            "name": resource["author"],
            "thumbnail": {
                "url": resource["download_url"],
            },
            "url": resource["download_url"],
            "contentType": "image/jpeg"
        }
        resources.append(content)

    print(resources)

    return {"type": "SUCCESS","resources":resources}

if __name__ == "__main__":
    app.run(host="127.0.0.1", port=8080, debug=True)

Run the server with python3 main.py, and expose it to the internet using a tuneling software like ngrok, or you can do what I did, and hosted it on PythonAnywhere.

You can see it in action here - https://ajotwani.pythonanywhere.com/canva/content/resources/find

My Flask server listening and responding to POST request from Canvac

Step 2: Build the app on Canva developer portal.

Same as step 2 here

Step 3: Configure the content extension

Same as step 3 here

Tagged in: