A developer building a CrewAI pipeline that reads Figma Community pages needs structured listing data before passing it into an agent context. Figma Community pages mix the core listing content with navigation, sidebars, and related resource links, and scraping them by hand requires CSS selectors that break when Figma updates its layout. EnConvert Distill accepts up to 50 Figma Community page URLs and a schema, then returns a results array normalised to exactly that schema in one synchronous call. The extracted page data is ready to pass into a CrewAI agent context with no HTML parsing.
How to Summarise Figma Community with CrewAI
Use EnConvert Distill to extract structured data from Figma Community pages inside a CrewAI pipeline from up to 50 URLs in a single synchronous API call
Get API keyExample
python
import os
import requests
from crewai import Agent, Crew, Process, Task
from crewai.tools import BaseTool
from pydantic import BaseModel, Field
BASE_URL = "https://api.enconvert.com/v2"
HEADERS = {"X-API-Key": os.environ["ENCONVERT_API_KEY"], "Content-Type": "application/json"}
LISTING_SCHEMA = {
"title": "The name of the community resource",
"description": "The description text of the listing, without navigation or related resources",
"creator": "The name of the creator or publisher of the resource",
"category": "The type of resource, such as plugin, widget, template, or file",
"tags": "The tags shown on the listing",
}
class FigmaCommunityInput(BaseModel):
urls: list[str] = Field(description="Figma Community page URLs to read, at most 50 per call")
class FigmaCommunityTool(BaseTool):
name: str = "read_figma_community_pages"
description: str = (
"Reads Figma Community listing pages and returns structured fields for each page: "
"title, description, creator, category, and tags."
)
args_schema: type[BaseModel] = FigmaCommunityInput
def _run(self, urls: list[str]) -> str:
if len(urls) > 50:
return "Too many URLs. Distill accepts at most 50 per call."
response = requests.post(
f"{BASE_URL}/distill",
headers=HEADERS,
json={"urls": urls, "schema": LISTING_SCHEMA},
timeout=120,
)
if response.status_code == 402:
return "Distill requires a paid plan."
response.raise_for_status()
entries = []
for result in response.json()["results"]:
if result["status"] != "completed":
entries.append(f"Source: {result['url']}\nCould not be read ({result['status']}).")
continue
rq = result.get("render_quality", 1.0)
if rq < 0.5:
entries.append(f"Source: {result['url']}\nLow render quality ({rq:.2f}), skipped.")
continue
data = result.get("data") or {}
tags = data.get("tags")
entries.append(
f"Source: {result['url']}\n"
f"Title: {data.get('title')}\n"
f"Creator: {data.get('creator')}\n"
f"Category: {data.get('category')}\n"
f"Tags: {', '.join(tags) if isinstance(tags, list) else tags}\n\n"
f"{data.get('description')}"
)
if not entries:
return "No Figma Community pages could be extracted."
return "\n\n---\n\n".join(entries)
FIGMA_URLS = [url.strip() for url in os.environ["FIGMA_COMMUNITY_URLS"].split(",")] # two public Figma Community plugin or template URLs
# CrewAI's default LLM reads OPENAI_API_KEY from the environment
researcher = Agent(
role="Figma Community Researcher",
goal="Answer questions about Figma Community plugins and templates using only the listings you read",
backstory="You review design plugins and templates and cite the listing behind every statement.",
tools=[FigmaCommunityTool()],
allow_delegation=False,
verbose=True,
llm="gpt-4.1",
)
task = Task(
description=(
"Read these Figma Community listings: "
f"{' and '.join(FIGMA_URLS)}. "
"Compare what each one does, who made it, and how it is categorised, "
"and cite the source URL for each point."
),
expected_output="A short comparison of the two resources, with a source URL for each point.",
agent=researcher,
)
crew = Crew(agents=[researcher], tasks=[task], process=Process.sequential, verbose=True)
print(crew.kickoff())
What you get back
Distill returns a results array with one entry per URL, each holding a data object normalised to the schema’s keys, regardless of the surrounding navigation or Figma Community layout. Scraping Figma Community pages by hand requires CSS selectors that break when Figma updates its layout, and passing raw page HTML into a CrewAI agent fills the context with navigation and boilerplate that reduces the quality of the agent’s output.
Distill runs on paid plans only, and the free tier returns a 402 for this endpoint, so the free key covers EnConvert’s other endpoints.