{ "openapi": "3.1.0", "paths": { "/v1/publications/{publicationId}": { "get": { "description": "Retrieve detailed information about a specific publication", "summary": "Get publication by ID", "tags": [ "publications" ], "parameters": [ { "name": "publicationId", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Unique identifier of the publication" } ], "responses": { "200": { "description": "Publication details retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the publication" }, "name": { "type": "string", "description": "Display name of the publication" }, "ownerUserId": { "type": "string", "description": "ID of the user who owns this publication" }, "slug": { "type": "string", "minLength": 1, "maxLength": 256, "description": "URL-friendly identifier for the publication; accessible at paragraph.com/@[slug]" }, "customDomain": { "type": "string", "format": "uri", "description": "Custom domain configured for this publication" }, "summary": { "type": "string", "maxLength": 500, "description": "Brief description of the publication (max 500 characters)" }, "logoUrl": { "type": "string", "format": "uri", "description": "URL to the publication's logo image" }, "postListType": { "type": "string", "enum": [ "feed", "grid", "full-post" ], "description": "Homepage layout. 'feed' is a single-column list of cards, 'grid' is a 3-column grid, 'full-post' shows full posts in a single column." }, "themeColor": { "type": "string", "enum": [ "default", "orange-500", "rose-600", "pink-500", "fuchsia-600", "purple-600", "violet-600", "indigo-600", "blue-600", "sky-600", "cyan-600", "teal-600", "emerald-600", "green-600", "lime-600", "yellow-700", "amber-600", "orange-600", "stone-800", "rose-900", "indigo-950", "teal-950", "lime-950", "orange-950" ], "description": "Theme accent color for the publication" }, "headerFont": { "type": "string", "enum": [ "default", "serif", "mono" ], "description": "Font family used for headers" }, "bodyFont": { "type": "string", "enum": [ "default", "serif", "mono" ], "description": "Font family used for body text" }, "showMostPopular": { "type": "boolean", "description": "Whether the 'most popular posts' widget is shown" }, "hideStats": { "type": "boolean", "description": "Whether to hide stats like subscriber count, post count, and collects" }, "featuredPost": { "type": "string", "minLength": 1, "description": "Featured post selector. Use 'latest' for the most recent post, 'popular' for the most-viewed post, 'disabled' to hide the featured slot, or the ID of a specific post in this publication." }, "enableTableOfContents": { "type": "boolean", "description": "Whether the table of contents is enabled on posts" }, "enableSubscribePopup": { "type": "boolean", "description": "Whether to show the subscribe popup to first-time visitors arriving from external links" }, "enableSubscribeScroll": { "type": "boolean", "description": "Whether to show the subscribe popup when first-time visitors scroll a post" }, "pinnedPostIds": { "type": "array", "items": { "type": "string" }, "description": "Ordered list of post IDs pinned to the top of the publication's homepage. Pinned posts render in their own section above the regular feed." }, "emailNotifications": { "type": "object", "properties": { "newSubscriber": { "type": "boolean", "description": "Email the writer when a new free subscriber signs up" } }, "description": "Owner-side email notification toggles" } }, "required": [ "id", "name", "ownerUserId", "slug" ] } } } }, "404": { "description": "Publication not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getPublicationById", "x-mint": { "mcp": { "enabled": true, "name": "get-publication-by-id", "description": "Get a publication by its unique ID" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Get publication by ID", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst publication = await api.publications.get({ id: \"BMV6abfvCSUl51ErCVzd\" }).single()" } ] }, "patch": { "description": "Update settings for a publication. The publication is identified by the API key provided in the Authorization header, and the path `:publicationId` must match the publication that owns the API key.\n\n**Behavior:**\n- Only provided fields are updated; omitted fields remain unchanged\n- Unknown or removed settings are rejected. The legacy `disableHighlights` setting is no longer supported and must be removed from requests.\n- Set `featuredPost` to `\"latest\"`, `\"popular\"`, `\"disabled\"`, or a specific post ID. The post must belong to this publication.\n- `pinnedPostIds` replaces the existing pinned list. Pinned posts are hidden from the regular feed (they show in their own section), and unpinned posts return to the feed.\n- `emailNotifications` is merged onto the current settings; only the toggles you send are changed.", "summary": "Update publication settings", "tags": [ "publications" ], "parameters": [ { "name": "publicationId", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Unique identifier of the publication to update" } ], "requestBody": { "description": "Body", "content": { "application/json": { "schema": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 100, "description": "Display name of the publication" }, "summary": { "type": "string", "maxLength": 500, "description": "Brief description of the publication (max 500 characters)" }, "postListType": { "type": "string", "enum": [ "feed", "grid", "full-post" ], "description": "Homepage layout. 'feed' is a single-column list of cards, 'grid' is a 3-column grid, 'full-post' shows full posts in a single column." }, "themeColor": { "type": "string", "enum": [ "default", "orange-500", "rose-600", "pink-500", "fuchsia-600", "purple-600", "violet-600", "indigo-600", "blue-600", "sky-600", "cyan-600", "teal-600", "emerald-600", "green-600", "lime-600", "yellow-700", "amber-600", "orange-600", "stone-800", "rose-900", "indigo-950", "teal-950", "lime-950", "orange-950" ], "description": "Theme accent color for the publication" }, "headerFont": { "type": "string", "enum": [ "default", "serif", "mono" ], "description": "Font family used for headers" }, "bodyFont": { "type": "string", "enum": [ "default", "serif", "mono" ], "description": "Font family used for body text" }, "showMostPopular": { "type": "boolean", "description": "Whether to show the 'most popular posts' widget" }, "hideStats": { "type": "boolean", "description": "Whether to hide stats like subscriber count, post count, and collects" }, "featuredPost": { "type": "string", "minLength": 1, "description": "Featured post selector. Use 'latest' for the most recent post, 'popular' for the most-viewed post, 'disabled' to hide the featured slot, or the ID of a specific post in this publication." }, "enableTableOfContents": { "type": "boolean", "description": "Whether the table of contents is enabled on posts" }, "enableSubscribePopup": { "type": "boolean", "description": "Whether to show the subscribe popup to first-time visitors arriving from external links" }, "enableSubscribeScroll": { "type": "boolean", "description": "Whether to show the subscribe popup when first-time visitors scroll a post" }, "pinnedPostIds": { "type": "array", "items": { "type": "string", "minLength": 1, "maxLength": 64 }, "maxItems": 50, "description": "Ordered list of post IDs to pin to the top of the homepage. Each ID must belong to this publication. Replaces the existing pinned list. Maximum 50 IDs." }, "emailNotifications": { "type": "object", "properties": { "newSubscriber": { "type": "boolean", "description": "Email the writer when a new free subscriber signs up" } }, "description": "Owner-side email notification toggles" } }, "additionalProperties": false } } } }, "responses": { "200": { "description": "Publication updated successfully — returns the updated publication", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the publication" }, "name": { "type": "string", "description": "Display name of the publication" }, "ownerUserId": { "type": "string", "description": "ID of the user who owns this publication" }, "slug": { "type": "string", "minLength": 1, "maxLength": 256, "description": "URL-friendly identifier for the publication; accessible at paragraph.com/@[slug]" }, "customDomain": { "type": "string", "format": "uri", "description": "Custom domain configured for this publication" }, "summary": { "type": "string", "maxLength": 500, "description": "Brief description of the publication (max 500 characters)" }, "logoUrl": { "type": "string", "format": "uri", "description": "URL to the publication's logo image" }, "postListType": { "type": "string", "enum": [ "feed", "grid", "full-post" ], "description": "Homepage layout. 'feed' is a single-column list of cards, 'grid' is a 3-column grid, 'full-post' shows full posts in a single column." }, "themeColor": { "type": "string", "enum": [ "default", "orange-500", "rose-600", "pink-500", "fuchsia-600", "purple-600", "violet-600", "indigo-600", "blue-600", "sky-600", "cyan-600", "teal-600", "emerald-600", "green-600", "lime-600", "yellow-700", "amber-600", "orange-600", "stone-800", "rose-900", "indigo-950", "teal-950", "lime-950", "orange-950" ], "description": "Theme accent color for the publication" }, "headerFont": { "type": "string", "enum": [ "default", "serif", "mono" ], "description": "Font family used for headers" }, "bodyFont": { "type": "string", "enum": [ "default", "serif", "mono" ], "description": "Font family used for body text" }, "showMostPopular": { "type": "boolean", "description": "Whether the 'most popular posts' widget is shown" }, "hideStats": { "type": "boolean", "description": "Whether to hide stats like subscriber count, post count, and collects" }, "featuredPost": { "type": "string", "minLength": 1, "description": "Featured post selector. Use 'latest' for the most recent post, 'popular' for the most-viewed post, 'disabled' to hide the featured slot, or the ID of a specific post in this publication." }, "enableTableOfContents": { "type": "boolean", "description": "Whether the table of contents is enabled on posts" }, "enableSubscribePopup": { "type": "boolean", "description": "Whether to show the subscribe popup to first-time visitors arriving from external links" }, "enableSubscribeScroll": { "type": "boolean", "description": "Whether to show the subscribe popup when first-time visitors scroll a post" }, "pinnedPostIds": { "type": "array", "items": { "type": "string" }, "description": "Ordered list of post IDs pinned to the top of the publication's homepage. Pinned posts render in their own section above the regular feed." }, "emailNotifications": { "type": "object", "properties": { "newSubscriber": { "type": "boolean", "description": "Email the writer when a new free subscriber signs up" } }, "description": "Owner-side email notification toggles" } }, "required": [ "id", "name", "ownerUserId", "slug" ] } } } }, "400": { "description": "Invalid request — check field values", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "403": { "description": "API key does not have access to this publication", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "404": { "description": "Publication not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "updatePublication", "x-mint": { "mcp": { "enabled": true, "name": "update-publication", "description": "Update settings for a publication, including theme, featured post, and behavior toggles" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Set a featured post", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nawait api.publications.update({\n id: \"BMV6abfvCSUl51ErCVzd\",\n featuredPost: \"3T2PQZlsdQtigUp4fhlb\",\n})" }, { "lang": "typescript", "label": "Update theme settings", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nawait api.publications.update({\n id: \"BMV6abfvCSUl51ErCVzd\",\n themeColor: \"indigo-600\",\n headerFont: \"serif\",\n postListType: \"grid\",\n})" } ], "security": [ { "apiKey": [] } ] } }, "/v1/publications/slug/{slug}": { "get": { "description": "Retrieve publication details using its URL-friendly slug. Optionally include an @ before the slug.", "summary": "Get publication by slug", "tags": [ "publications" ], "parameters": [ { "name": "slug", "in": "path", "required": true, "schema": { "type": "string", "minLength": 1, "maxLength": 256 }, "description": "URL-friendly identifier of the publication" } ], "responses": { "200": { "description": "Publication details retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the publication" }, "name": { "type": "string", "description": "Display name of the publication" }, "ownerUserId": { "type": "string", "description": "ID of the user who owns this publication" }, "slug": { "type": "string", "minLength": 1, "maxLength": 256, "description": "URL-friendly identifier for the publication; accessible at paragraph.com/@[slug]" }, "customDomain": { "type": "string", "format": "uri", "description": "Custom domain configured for this publication" }, "summary": { "type": "string", "maxLength": 500, "description": "Brief description of the publication (max 500 characters)" }, "logoUrl": { "type": "string", "format": "uri", "description": "URL to the publication's logo image" }, "postListType": { "type": "string", "enum": [ "feed", "grid", "full-post" ], "description": "Homepage layout. 'feed' is a single-column list of cards, 'grid' is a 3-column grid, 'full-post' shows full posts in a single column." }, "themeColor": { "type": "string", "enum": [ "default", "orange-500", "rose-600", "pink-500", "fuchsia-600", "purple-600", "violet-600", "indigo-600", "blue-600", "sky-600", "cyan-600", "teal-600", "emerald-600", "green-600", "lime-600", "yellow-700", "amber-600", "orange-600", "stone-800", "rose-900", "indigo-950", "teal-950", "lime-950", "orange-950" ], "description": "Theme accent color for the publication" }, "headerFont": { "type": "string", "enum": [ "default", "serif", "mono" ], "description": "Font family used for headers" }, "bodyFont": { "type": "string", "enum": [ "default", "serif", "mono" ], "description": "Font family used for body text" }, "showMostPopular": { "type": "boolean", "description": "Whether the 'most popular posts' widget is shown" }, "hideStats": { "type": "boolean", "description": "Whether to hide stats like subscriber count, post count, and collects" }, "featuredPost": { "type": "string", "minLength": 1, "description": "Featured post selector. Use 'latest' for the most recent post, 'popular' for the most-viewed post, 'disabled' to hide the featured slot, or the ID of a specific post in this publication." }, "enableTableOfContents": { "type": "boolean", "description": "Whether the table of contents is enabled on posts" }, "enableSubscribePopup": { "type": "boolean", "description": "Whether to show the subscribe popup to first-time visitors arriving from external links" }, "enableSubscribeScroll": { "type": "boolean", "description": "Whether to show the subscribe popup when first-time visitors scroll a post" }, "pinnedPostIds": { "type": "array", "items": { "type": "string" }, "description": "Ordered list of post IDs pinned to the top of the publication's homepage. Pinned posts render in their own section above the regular feed." }, "emailNotifications": { "type": "object", "properties": { "newSubscriber": { "type": "boolean", "description": "Email the writer when a new free subscriber signs up" } }, "description": "Owner-side email notification toggles" } }, "required": [ "id", "name", "ownerUserId", "slug" ] } } } }, "404": { "description": "Publication not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getPublicationBySlug", "x-mint": { "mcp": { "enabled": true, "name": "get-publication-by-slug", "description": "Get a publication by its URL-friendly slug (for example, for URL paragraph.com/@blog, the slug would be 'blog'" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Get publication by slug", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst publication = await api.publications.get({ slug: \"@blog\" }).single()" } ] } }, "/v1/publications/domain/{domain}": { "get": { "description": "Retrieve publication details using its custom domain", "summary": "Get publication by custom domain", "tags": [ "publications" ], "parameters": [ { "name": "domain", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Custom domain of the publication" } ], "responses": { "200": { "description": "Publication details retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the publication" }, "name": { "type": "string", "description": "Display name of the publication" }, "ownerUserId": { "type": "string", "description": "ID of the user who owns this publication" }, "slug": { "type": "string", "minLength": 1, "maxLength": 256, "description": "URL-friendly identifier for the publication; accessible at paragraph.com/@[slug]" }, "customDomain": { "type": "string", "format": "uri", "description": "Custom domain configured for this publication" }, "summary": { "type": "string", "maxLength": 500, "description": "Brief description of the publication (max 500 characters)" }, "logoUrl": { "type": "string", "format": "uri", "description": "URL to the publication's logo image" }, "postListType": { "type": "string", "enum": [ "feed", "grid", "full-post" ], "description": "Homepage layout. 'feed' is a single-column list of cards, 'grid' is a 3-column grid, 'full-post' shows full posts in a single column." }, "themeColor": { "type": "string", "enum": [ "default", "orange-500", "rose-600", "pink-500", "fuchsia-600", "purple-600", "violet-600", "indigo-600", "blue-600", "sky-600", "cyan-600", "teal-600", "emerald-600", "green-600", "lime-600", "yellow-700", "amber-600", "orange-600", "stone-800", "rose-900", "indigo-950", "teal-950", "lime-950", "orange-950" ], "description": "Theme accent color for the publication" }, "headerFont": { "type": "string", "enum": [ "default", "serif", "mono" ], "description": "Font family used for headers" }, "bodyFont": { "type": "string", "enum": [ "default", "serif", "mono" ], "description": "Font family used for body text" }, "showMostPopular": { "type": "boolean", "description": "Whether the 'most popular posts' widget is shown" }, "hideStats": { "type": "boolean", "description": "Whether to hide stats like subscriber count, post count, and collects" }, "featuredPost": { "type": "string", "minLength": 1, "description": "Featured post selector. Use 'latest' for the most recent post, 'popular' for the most-viewed post, 'disabled' to hide the featured slot, or the ID of a specific post in this publication." }, "enableTableOfContents": { "type": "boolean", "description": "Whether the table of contents is enabled on posts" }, "enableSubscribePopup": { "type": "boolean", "description": "Whether to show the subscribe popup to first-time visitors arriving from external links" }, "enableSubscribeScroll": { "type": "boolean", "description": "Whether to show the subscribe popup when first-time visitors scroll a post" }, "pinnedPostIds": { "type": "array", "items": { "type": "string" }, "description": "Ordered list of post IDs pinned to the top of the publication's homepage. Pinned posts render in their own section above the regular feed." }, "emailNotifications": { "type": "object", "properties": { "newSubscriber": { "type": "boolean", "description": "Email the writer when a new free subscriber signs up" } }, "description": "Owner-side email notification toggles" } }, "required": [ "id", "name", "ownerUserId", "slug" ] } } } }, "404": { "description": "Publication not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getPublicationByDomain", "x-mint": { "mcp": { "enabled": true, "name": "get-publication-by-domain", "description": "Get a publication by its custom domain" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Get publication by domain", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst publication = await api.publications.get({ domain: \"avc.xyz\" }).single()" } ] } }, "/v1/publications/{publicationId}/subscribers/count": { "get": { "description": "Retrieve the total number of subscribers for a publication", "summary": "Get subscriber count", "tags": [ "publications" ], "parameters": [ { "name": "publicationId", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Unique identifier of the publication" } ], "responses": { "200": { "description": "Subscriber count retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "count": { "type": "number", "description": "Total number of subscribers" } }, "required": [ "count" ] } } } }, "404": { "description": "Publication not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getSubscriberCount", "x-mint": { "mcp": { "enabled": true, "name": "get-subscriber-count", "description": "Get the total number of subscribers for a publication" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Get subscriber count", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst count = await api.subscribers.getCount({ id: \"BMV6abfvCSUl51ErCVzd\" })" } ] } }, "/v1/posts/feed": { "get": { "description": "Retrieve a curated, paginated list of posts.", "summary": "Get posts feed", "tags": [ "posts" ], "parameters": [ { "name": "cursor", "in": "query", "description": "Cursor for pagination", "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of items to return (1-60, default: 20)", "schema": { "default": 20, "type": "integer", "minimum": 1, "maximum": 60 } }, { "name": "includeContent", "in": "query", "description": "Include full content fields (json, staticHtml, markdown) in the post. Default: false", "schema": { "oneOf": [ { "type": "boolean" }, { "type": "string" } ] } } ], "responses": { "200": { "description": "Feed items retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "items": { "type": "array", "items": { "type": "object", "properties": { "post": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the post" }, "title": { "type": "string", "maxLength": 200, "description": "Title of the post" }, "imageUrl": { "type": "string", "format": "uri", "description": "Optional URL to the post's main image" }, "publishedAt": { "type": "string", "description": "Epoch timestamp when the post was published" }, "updatedAt": { "type": "string", "description": "Epoch timestamp when the post was last updated" }, "subtitle": { "type": "string", "maxLength": 300, "description": "Optional subtitle or brief summary" }, "slug": { "type": "string", "minLength": 1, "maxLength": 256, "description": "URL-friendly identifier for the post; accessible at paragraph.com/@[publicationSlug]/[slug]" }, "staticHtml": { "type": "string", "description": "Rendered HTML content of the post" }, "json": { "type": "string", "description": "TipTap JSON representation of the post content structure. This is the source of truth that the staticHtml and markdown is generated from" }, "markdown": { "type": "string", "description": "Markdown source of the post content" }, "coinId": { "type": "string", "description": "ID of the associated coin, if the post is coined" }, "categories": { "type": "array", "items": { "type": "string" }, "description": "Categories/tags associated with this post" }, "authors": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the user" }, "walletAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Wallet address of the user" }, "avatarUrl": { "type": "string", "format": "uri", "description": "URL to the user's avatar image" }, "publicationId": { "type": "string", "description": "ID of the publication this user belongs to" }, "name": { "type": "string", "description": "Display name of the user" }, "bio": { "type": "string", "maxLength": 500, "description": "Brief biography of the user (max 500 characters)" } }, "required": [ "id", "publicationId" ] }, "description": "Authors of this post" }, "authorIds": { "type": "array", "items": { "type": "string" }, "description": "IDs of the authors of this post" }, "views": { "type": "number", "description": "Total views. Only included when fetching your own posts via GET /v1/posts" }, "status": { "type": "string", "enum": [ "published", "draft", "scheduled", "archived" ], "description": "Current publish status. Only set on authenticated endpoints (listOwn, getById for your own post). Use this instead of publishedAt to determine publish state — publishedAt is preserved across unpublishing." } }, "required": [ "id", "title", "slug" ], "description": "The post content" }, "publication": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the publication" }, "name": { "type": "string", "description": "Display name of the publication" }, "ownerUserId": { "type": "string", "description": "ID of the user who owns this publication" }, "slug": { "type": "string", "minLength": 1, "maxLength": 256, "description": "URL-friendly identifier for the publication; accessible at paragraph.com/@[slug]" }, "customDomain": { "type": "string", "format": "uri", "description": "Custom domain configured for this publication" }, "summary": { "type": "string", "maxLength": 500, "description": "Brief description of the publication (max 500 characters)" }, "logoUrl": { "type": "string", "format": "uri", "description": "URL to the publication's logo image" }, "postListType": { "type": "string", "enum": [ "feed", "grid", "full-post" ], "description": "Homepage layout. 'feed' is a single-column list of cards, 'grid' is a 3-column grid, 'full-post' shows full posts in a single column." }, "themeColor": { "type": "string", "enum": [ "default", "orange-500", "rose-600", "pink-500", "fuchsia-600", "purple-600", "violet-600", "indigo-600", "blue-600", "sky-600", "cyan-600", "teal-600", "emerald-600", "green-600", "lime-600", "yellow-700", "amber-600", "orange-600", "stone-800", "rose-900", "indigo-950", "teal-950", "lime-950", "orange-950" ], "description": "Theme accent color for the publication" }, "headerFont": { "type": "string", "enum": [ "default", "serif", "mono" ], "description": "Font family used for headers" }, "bodyFont": { "type": "string", "enum": [ "default", "serif", "mono" ], "description": "Font family used for body text" }, "showMostPopular": { "type": "boolean", "description": "Whether the 'most popular posts' widget is shown" }, "hideStats": { "type": "boolean", "description": "Whether to hide stats like subscriber count, post count, and collects" }, "featuredPost": { "type": "string", "minLength": 1, "description": "Featured post selector. Use 'latest' for the most recent post, 'popular' for the most-viewed post, 'disabled' to hide the featured slot, or the ID of a specific post in this publication." }, "enableTableOfContents": { "type": "boolean", "description": "Whether the table of contents is enabled on posts" }, "enableSubscribePopup": { "type": "boolean", "description": "Whether to show the subscribe popup to first-time visitors arriving from external links" }, "enableSubscribeScroll": { "type": "boolean", "description": "Whether to show the subscribe popup when first-time visitors scroll a post" }, "pinnedPostIds": { "type": "array", "items": { "type": "string" }, "description": "Ordered list of post IDs pinned to the top of the publication's homepage. Pinned posts render in their own section above the regular feed." }, "emailNotifications": { "type": "object", "properties": { "newSubscriber": { "type": "boolean", "description": "Email the writer when a new free subscriber signs up" } }, "description": "Owner-side email notification toggles" } }, "required": [ "id", "name", "ownerUserId", "slug" ], "description": "The publication this post belongs to" }, "user": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the user" }, "walletAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Wallet address of the user" }, "avatarUrl": { "type": "string", "format": "uri", "description": "URL to the user's avatar image" }, "publicationId": { "type": "string", "description": "ID of the publication this user belongs to" }, "name": { "type": "string", "description": "Display name of the user" }, "bio": { "type": "string", "maxLength": 500, "description": "Brief biography of the user (max 500 characters)" } }, "required": [ "id", "publicationId" ], "description": "The user who owns the publication this post belongs to" } }, "required": [ "post", "publication", "user" ] }, "description": "Array of items in this page" }, "pagination": { "type": "object", "properties": { "cursor": { "type": "string", "description": "Cursor for fetching the next page of results" }, "hasMore": { "type": "boolean", "description": "Whether more results are available" }, "total": { "type": "number", "description": "Total number of items available" } }, "required": [ "hasMore" ] } }, "required": [ "items", "pagination" ] } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getPostsFeed", "x-mint": { "mcp": { "enabled": true, "name": "get-posts-feed", "description": "Get curated home feed posts" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Get feed posts with pagination", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst { items, pagination } = await api.feed.get({ limit: 20 })" } ] } }, "/v1/posts/tag/{tag}": { "get": { "description": "Retrieve a paginated list of posts with a specific tag, sorted by publish date (newest first)", "summary": "Get posts by tag", "tags": [ "posts" ], "parameters": [ { "name": "tag", "in": "path", "required": true, "schema": { "type": "string", "minLength": 1 }, "description": "Tag to filter posts by" }, { "name": "cursor", "in": "query", "description": "Cursor for pagination", "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of items to return (1-100, default: 10)", "schema": { "default": 10, "type": "integer", "minimum": 1, "maximum": 100 } }, { "name": "includeContent", "in": "query", "description": "Include full content fields (json, staticHtml, markdown) in the post. Default: false", "schema": { "oneOf": [ { "type": "boolean" }, { "type": "string" } ] } } ], "responses": { "200": { "description": "Posts retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "items": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the post" }, "title": { "type": "string", "maxLength": 200, "description": "Title of the post" }, "imageUrl": { "type": "string", "format": "uri", "description": "Optional URL to the post's main image" }, "publishedAt": { "type": "string", "description": "Epoch timestamp when the post was published" }, "updatedAt": { "type": "string", "description": "Epoch timestamp when the post was last updated" }, "subtitle": { "type": "string", "maxLength": 300, "description": "Optional subtitle or brief summary" }, "slug": { "type": "string", "minLength": 1, "maxLength": 256, "description": "URL-friendly identifier for the post; accessible at paragraph.com/@[publicationSlug]/[slug]" }, "staticHtml": { "type": "string", "description": "Rendered HTML content of the post" }, "json": { "type": "string", "description": "TipTap JSON representation of the post content structure. This is the source of truth that the staticHtml and markdown is generated from" }, "markdown": { "type": "string", "description": "Markdown source of the post content" }, "coinId": { "type": "string", "description": "ID of the associated coin, if the post is coined" }, "categories": { "type": "array", "items": { "type": "string" }, "description": "Categories/tags associated with this post" }, "authors": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the user" }, "walletAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Wallet address of the user" }, "avatarUrl": { "type": "string", "format": "uri", "description": "URL to the user's avatar image" }, "publicationId": { "type": "string", "description": "ID of the publication this user belongs to" }, "name": { "type": "string", "description": "Display name of the user" }, "bio": { "type": "string", "maxLength": 500, "description": "Brief biography of the user (max 500 characters)" } }, "required": [ "id", "publicationId" ] }, "description": "Authors of this post" }, "authorIds": { "type": "array", "items": { "type": "string" }, "description": "IDs of the authors of this post" }, "views": { "type": "number", "description": "Total views. Only included when fetching your own posts via GET /v1/posts" }, "status": { "type": "string", "enum": [ "published", "draft", "scheduled", "archived" ], "description": "Current publish status. Only set on authenticated endpoints (listOwn, getById for your own post). Use this instead of publishedAt to determine publish state — publishedAt is preserved across unpublishing." } }, "required": [ "id", "title", "slug" ] }, "description": "Array of items in this page" }, "pagination": { "type": "object", "properties": { "cursor": { "type": "string", "description": "Cursor for fetching the next page of results" }, "hasMore": { "type": "boolean", "description": "Whether more results are available" }, "total": { "type": "number", "description": "Total number of items available" } }, "required": [ "hasMore" ] } }, "required": [ "items", "pagination" ] } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getPostsByTag", "x-mint": { "mcp": { "enabled": true, "name": "list-posts-by-tag", "description": "Get posts with a specific tag" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Get posts by tag with pagination", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst { items, pagination } = await api.posts.get({ tag: \"crypto\", limit: 20 })" } ] } }, "/v1/publications/{publicationId}/posts": { "get": { "description": "Retrieve a paginated list of published posts from a publication", "summary": "Get posts in a publication", "tags": [ "posts" ], "parameters": [ { "name": "publicationId", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Unique identifier of the publication" }, { "name": "cursor", "in": "query", "description": "Cursor for pagination", "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of items to return (1-100, default: 10)", "schema": { "default": 10, "type": "integer", "minimum": 1, "maximum": 100 } }, { "name": "includeContent", "in": "query", "description": "Include full content fields (markdown, json, staticHtml). Default: false", "schema": { "oneOf": [ { "type": "boolean" }, { "type": "string" } ] } } ], "responses": { "200": { "description": "Posts retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "items": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the post" }, "title": { "type": "string", "maxLength": 200, "description": "Title of the post" }, "imageUrl": { "type": "string", "format": "uri", "description": "Optional URL to the post's main image" }, "publishedAt": { "type": "string", "description": "Epoch timestamp when the post was published" }, "updatedAt": { "type": "string", "description": "Epoch timestamp when the post was last updated" }, "subtitle": { "type": "string", "maxLength": 300, "description": "Optional subtitle or brief summary" }, "slug": { "type": "string", "minLength": 1, "maxLength": 256, "description": "URL-friendly identifier for the post; accessible at paragraph.com/@[publicationSlug]/[slug]" }, "staticHtml": { "type": "string", "description": "Rendered HTML content of the post" }, "json": { "type": "string", "description": "TipTap JSON representation of the post content structure. This is the source of truth that the staticHtml and markdown is generated from" }, "markdown": { "type": "string", "description": "Markdown source of the post content" }, "coinId": { "type": "string", "description": "ID of the associated coin, if the post is coined" }, "categories": { "type": "array", "items": { "type": "string" }, "description": "Categories/tags associated with this post" }, "authors": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the user" }, "walletAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Wallet address of the user" }, "avatarUrl": { "type": "string", "format": "uri", "description": "URL to the user's avatar image" }, "publicationId": { "type": "string", "description": "ID of the publication this user belongs to" }, "name": { "type": "string", "description": "Display name of the user" }, "bio": { "type": "string", "maxLength": 500, "description": "Brief biography of the user (max 500 characters)" } }, "required": [ "id", "publicationId" ] }, "description": "Authors of this post" }, "authorIds": { "type": "array", "items": { "type": "string" }, "description": "IDs of the authors of this post" }, "views": { "type": "number", "description": "Total views. Only included when fetching your own posts via GET /v1/posts" }, "status": { "type": "string", "enum": [ "published", "draft", "scheduled", "archived" ], "description": "Current publish status. Only set on authenticated endpoints (listOwn, getById for your own post). Use this instead of publishedAt to determine publish state — publishedAt is preserved across unpublishing." } }, "required": [ "id", "title", "slug" ] }, "description": "Array of items in this page" }, "pagination": { "type": "object", "properties": { "cursor": { "type": "string", "description": "Cursor for fetching the next page of results" }, "hasMore": { "type": "boolean", "description": "Whether more results are available" }, "total": { "type": "number", "description": "Total number of items available" } }, "required": [ "hasMore" ] } }, "required": [ "items", "pagination" ] } } } }, "400": { "description": "Invalid request parameters", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getPosts", "x-mint": { "mcp": { "enabled": true, "name": "list-publication-posts", "description": "Get posts from a publication with pagination" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Get posts from a publication with pagination", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst { items: posts, pagination } = await api.posts.get({ publicationId: \"BMV6abfvCSUl51ErCVzd\" })" } ] } }, "/v1/posts/{postId}": { "get": { "description": "Retrieve detailed information about a specific post", "summary": "Get post by ID", "tags": [ "posts" ], "parameters": [ { "name": "postId", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Unique identifier of the post" }, { "name": "includeContent", "in": "query", "description": "Include full content fields (markdown, json, staticHtml). Default: false", "schema": { "oneOf": [ { "type": "boolean" }, { "type": "string" } ] } } ], "responses": { "200": { "description": "Post details retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the post" }, "title": { "type": "string", "maxLength": 200, "description": "Title of the post" }, "imageUrl": { "type": "string", "format": "uri", "description": "Optional URL to the post's main image" }, "publishedAt": { "type": "string", "description": "Epoch timestamp when the post was published" }, "updatedAt": { "type": "string", "description": "Epoch timestamp when the post was last updated" }, "subtitle": { "type": "string", "maxLength": 300, "description": "Optional subtitle or brief summary" }, "slug": { "type": "string", "minLength": 1, "maxLength": 256, "description": "URL-friendly identifier for the post; accessible at paragraph.com/@[publicationSlug]/[slug]" }, "staticHtml": { "type": "string", "description": "Rendered HTML content of the post" }, "json": { "type": "string", "description": "TipTap JSON representation of the post content structure. This is the source of truth that the staticHtml and markdown is generated from" }, "markdown": { "type": "string", "description": "Markdown source of the post content" }, "coinId": { "type": "string", "description": "ID of the associated coin, if the post is coined" }, "categories": { "type": "array", "items": { "type": "string" }, "description": "Categories/tags associated with this post" }, "authors": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the user" }, "walletAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Wallet address of the user" }, "avatarUrl": { "type": "string", "format": "uri", "description": "URL to the user's avatar image" }, "publicationId": { "type": "string", "description": "ID of the publication this user belongs to" }, "name": { "type": "string", "description": "Display name of the user" }, "bio": { "type": "string", "maxLength": 500, "description": "Brief biography of the user (max 500 characters)" } }, "required": [ "id", "publicationId" ] }, "description": "Authors of this post" }, "authorIds": { "type": "array", "items": { "type": "string" }, "description": "IDs of the authors of this post" }, "views": { "type": "number", "description": "Total views. Only included when fetching your own posts via GET /v1/posts" }, "status": { "type": "string", "enum": [ "published", "draft", "scheduled", "archived" ], "description": "Current publish status. Only set on authenticated endpoints (listOwn, getById for your own post). Use this instead of publishedAt to determine publish state — publishedAt is preserved across unpublishing." } }, "required": [ "id", "title", "slug" ] } } } }, "404": { "description": "Post not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getPostById", "x-mint": { "mcp": { "enabled": true, "name": "get-post-by-id", "description": "Get detailed information about a specific post by its ID" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Get post by ID", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst post = await api.posts.get({ id: \"3T2PQZlsdQtigUp4fhlb\" }).single()" } ] }, "put": { "description": "Update an existing post in your publication. The publication is identified by the API key provided in the Authorization header.\n\n**Behavior:**\n- Only provided fields are updated; omitted fields remain unchanged\n- When `markdown` is provided, it replaces the full content. Rich blocks (embeds, buttons, callouts) created in the editor will be lost — the markdown to editor conversion is lossy for blocks without a markdown equivalent\n- Set `status` to `\"published\"` to publish a draft, `\"draft\"` to unpublish, or `\"archived\"` to archive\n- When editing an already-live post that should remain live, include `status: \"published\"` in the update and verify the returned post status before telling the writer it is live\n- Set `scheduledAt` (Unix timestamp in milliseconds) to schedule a draft's first-publish for a future time. Must be in the future and at most 30 days out. Only valid for posts that haven't been published or already scheduled. Pass `scheduledAt: null` to cancel a previously scheduled publish (or to reschedule: cancel first, then schedule again with the new time). Set `sendNewsletter: true` alongside `scheduledAt` to email subscribers when the post publishes.\n- Set `imageUrl` to update the post's cover/hero image; the URL is fetched, re-hosted, and a placeholder is generated. Pass `clearImage: true` to remove the existing cover.", "summary": "Update a post by ID", "tags": [ "posts" ], "parameters": [ { "name": "postId", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Unique identifier of the post to update" } ], "requestBody": { "description": "Body", "content": { "application/json": { "schema": { "type": "object", "properties": { "markdown": { "type": "string", "description": "Post content in Markdown format. Replaces the FULL body. Markdown cannot represent buttons, linked images, or embedded media (videos, tweets, link cards) — replacing a post that has any of those with `markdown` drops them. Use `bodyJson` (round-tripped from get-post) to edit an existing post so nothing is lost. Provide `markdown` OR `bodyJson`, not both." }, "bodyJson": { "type": "string", "description": "Post content as a Tiptap document, JSON-stringified (e.g. '{\"type\":\"doc\",\"content\":[...]}'). This accepts ANY Tiptap node the editor supports — including videos, tweets, link cards, callouts, and buttons — so editing a post by round-tripping the `json` returned by get-post preserves everything markdown would drop. Replaces the FULL body; node-type validity is checked by the renderer and an unusable document is rejected. Provide `markdown` OR `bodyJson`, not both." }, "title": { "type": "string", "maxLength": 200, "description": "Title of the post" }, "subtitle": { "type": "string", "maxLength": 300, "description": "Optional subtitle or brief summary" }, "slug": { "type": "string", "minLength": 1, "maxLength": 256, "description": "URL-friendly identifier for the post" }, "postPreview": { "type": "string", "maxLength": 500, "description": "Preview text for the post" }, "categories": { "oneOf": [ { "type": "array", "items": { "type": "string" } }, { "type": "string" } ], "description": "Category tags for the post. Can also be a comma-separated string." }, "authorIds": { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 20, "description": "User ids credited as the post's authors, in byline order. Replaces the full list, so include every author you want kept — read the post's current `authorIds` first and start from those. Each id must be the publication's owner or an active team member; ids from outside the publication are rejected. There is no endpoint that enumerates members, so an id has to come from a post you have read (`authorIds` on a single post, or `authors[].id` on a list) or from the writer." }, "status": { "type": "string", "enum": [ "draft", "published", "archived" ], "description": "Set to 'published' to publish a draft or keep an already-live post published after edits, 'draft' to unpublish, or 'archived' to archive" }, "scheduledAt": { "description": "Unix timestamp (milliseconds) to schedule the post's first publish at a future time. Must be in the future and at most 30 days out. Only valid for draft posts that haven't been published or already scheduled. Cannot be combined with status: 'draft' or 'archived'. Pass null to cancel a previously scheduled publish. The value 0 is treated the same as omitting the field (no scheduling request); note that on an already-scheduled post, omitting `scheduledAt` while changing `status` cancels the schedule.", "type": [ "integer", "null" ], "minimum": 0 }, "sendNewsletter": { "oneOf": [ { "type": "boolean" }, { "type": "string", "enum": [ "true", "false", "1", "0" ] } ], "description": "Whether to send an email newsletter to subscribers when the post publishes. Only meaningful when publishing (status: 'published') or scheduling (scheduledAt set). Default: false" }, "publishedAt": { "type": "integer", "minimum": 0, "exclusiveMinimum": 0, "description": "Unix timestamp (milliseconds) to set as the post's publish date. Once set, the date is preserved across re-publishes." }, "imageUrl": { "type": "string", "format": "uri", "description": "URL of an image to set as the post's cover/hero image. The image is fetched, re-hosted on Paragraph's CDN, and a placeholder is generated. Pass clearImage: true instead to remove the existing cover." }, "clearImage": { "type": "boolean", "description": "When true, removes the post's existing cover/hero image. Ignored if imageUrl is also provided." } } } } } }, "responses": { "200": { "description": "Post updated successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ true ], "description": "Whether the update succeeded" } }, "required": [ "success" ] } } } }, "400": { "description": "Invalid request - check field values", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "404": { "description": "Post not found in your publication", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "409": { "description": "Conflict - the body change was refused because you weren't working from the post's current content: either you didn't call get-post before replacing the body, or the writer edited the post in the editor since you read it. Call get-post to read the current version, re-apply your change on it, and retry.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "updatePost", "x-mint": { "mcp": { "enabled": true, "name": "update-post", "description": "Update an existing post by its ID" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Update a post", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nawait api.posts.update({\n id: \"3T2PQZlsdQtigUp4fhlb\",\n title: \"Updated Title\",\n markdown: \"## New content\\n\\nUpdated post body.\",\n status: \"published\"\n})" }, { "lang": "typescript", "label": "Schedule a draft for a future publish", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nawait api.posts.update({\n id: \"3T2PQZlsdQtigUp4fhlb\",\n scheduledAt: Date.now() + 24 * 60 * 60 * 1000,\n})" }, { "lang": "typescript", "label": "Cancel a scheduled publish", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nawait api.posts.update({\n id: \"3T2PQZlsdQtigUp4fhlb\",\n scheduledAt: null,\n})" }, { "lang": "bash", "label": "Update post using curl", "source": "curl -X PUT \"https://public.api.paragraph.com/api/v1/posts/3T2PQZlsdQtigUp4fhlb\" \\\n -H \"Authorization: Bearer your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"title\": \"Updated Title\", \"markdown\": \"New content\"}'" } ], "security": [ { "apiKey": [] } ] }, "delete": { "description": "Permanently delete a post from your publication. The publication is identified by the API key provided in the Authorization header.\n\n**Warning:** This action is irreversible. The post and all related data (notifications and drafts) will be permanently deleted.", "summary": "Delete a post", "tags": [ "posts" ], "parameters": [ { "name": "postId", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Unique identifier of the post to delete" } ], "requestBody": { "description": "Body", "content": { "application/json": { "schema": { "type": "object", "properties": {} } } } }, "responses": { "200": { "description": "Post deleted successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ true ], "description": "Whether the deletion succeeded" } }, "required": [ "success" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "404": { "description": "Post not found in your publication", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "deletePost", "x-mint": { "mcp": { "enabled": true, "name": "delete-post", "description": "Permanently delete a post by its ID" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Delete a post", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nawait api.posts.delete({ id: \"3T2PQZlsdQtigUp4fhlb\" })" }, { "lang": "bash", "label": "Delete post using curl", "source": "curl -X DELETE \"https://public.api.paragraph.com/api/v1/posts/3T2PQZlsdQtigUp4fhlb\" \\\n -H \"Authorization: Bearer your-api-key\"" } ], "security": [ { "apiKey": [] } ] } }, "/v1/publications/{publicationId}/posts/slug/{postSlug}": { "get": { "description": "Retrieve a post using its publication ID and its URL-friendly slug", "summary": "Get post by publication ID and post slug", "tags": [ "posts" ], "parameters": [ { "name": "publicationId", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Unique identifier of the publication" }, { "name": "postSlug", "in": "path", "required": true, "schema": { "type": "string", "minLength": 1, "maxLength": 256 }, "description": "URL-friendly identifier of the post" }, { "name": "includeContent", "in": "query", "description": "Include full content fields (markdown, json, staticHtml). Default: false", "schema": { "oneOf": [ { "type": "boolean" }, { "type": "string" } ] } } ], "responses": { "200": { "description": "Post details retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the post" }, "title": { "type": "string", "maxLength": 200, "description": "Title of the post" }, "imageUrl": { "type": "string", "format": "uri", "description": "Optional URL to the post's main image" }, "publishedAt": { "type": "string", "description": "Epoch timestamp when the post was published" }, "updatedAt": { "type": "string", "description": "Epoch timestamp when the post was last updated" }, "subtitle": { "type": "string", "maxLength": 300, "description": "Optional subtitle or brief summary" }, "slug": { "type": "string", "minLength": 1, "maxLength": 256, "description": "URL-friendly identifier for the post; accessible at paragraph.com/@[publicationSlug]/[slug]" }, "staticHtml": { "type": "string", "description": "Rendered HTML content of the post" }, "json": { "type": "string", "description": "TipTap JSON representation of the post content structure. This is the source of truth that the staticHtml and markdown is generated from" }, "markdown": { "type": "string", "description": "Markdown source of the post content" }, "coinId": { "type": "string", "description": "ID of the associated coin, if the post is coined" }, "categories": { "type": "array", "items": { "type": "string" }, "description": "Categories/tags associated with this post" }, "authors": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the user" }, "walletAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Wallet address of the user" }, "avatarUrl": { "type": "string", "format": "uri", "description": "URL to the user's avatar image" }, "publicationId": { "type": "string", "description": "ID of the publication this user belongs to" }, "name": { "type": "string", "description": "Display name of the user" }, "bio": { "type": "string", "maxLength": 500, "description": "Brief biography of the user (max 500 characters)" } }, "required": [ "id", "publicationId" ] }, "description": "Authors of this post" }, "authorIds": { "type": "array", "items": { "type": "string" }, "description": "IDs of the authors of this post" }, "views": { "type": "number", "description": "Total views. Only included when fetching your own posts via GET /v1/posts" }, "status": { "type": "string", "enum": [ "published", "draft", "scheduled", "archived" ], "description": "Current publish status. Only set on authenticated endpoints (listOwn, getById for your own post). Use this instead of publishedAt to determine publish state — publishedAt is preserved across unpublishing." } }, "required": [ "id", "title", "slug" ] } } } }, "404": { "description": "Post not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getPostByPublicationIdAndPostSlug", "x-mint": { "mcp": { "enabled": true, "name": "get-post-by-publication-id-and-slug", "description": "Get a post using its publication ID and slug" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Get post by publication ID and slug", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst post = await api.posts.get({\n publicationId: \"BMV6abfvCSUl51ErCVzd\",\n slug: \"my-first-post\"\n}).single()" } ] } }, "/v1/publications/slug/{publicationSlug}/posts/slug/{postSlug}": { "get": { "description": "Retrieve a post using its publication's slug and the post's slug. This is useful for building user-facing URLs.", "summary": "Get post by publication slug and post slug", "tags": [ "posts" ], "parameters": [ { "name": "publicationSlug", "in": "path", "required": true, "schema": { "type": "string", "minLength": 1, "maxLength": 256 }, "description": "URL-friendly identifier of the publication, e.g. 'blog'" }, { "name": "postSlug", "in": "path", "required": true, "schema": { "type": "string", "minLength": 1, "maxLength": 256 }, "description": "URL-friendly identifier of the post, e.g. 'my-first-post'" }, { "name": "includeContent", "in": "query", "description": "Include full content fields (markdown, json, staticHtml). Default: false", "schema": { "oneOf": [ { "type": "boolean" }, { "type": "string" } ] } } ], "responses": { "200": { "description": "Post details retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the post" }, "title": { "type": "string", "maxLength": 200, "description": "Title of the post" }, "imageUrl": { "type": "string", "format": "uri", "description": "Optional URL to the post's main image" }, "publishedAt": { "type": "string", "description": "Epoch timestamp when the post was published" }, "updatedAt": { "type": "string", "description": "Epoch timestamp when the post was last updated" }, "subtitle": { "type": "string", "maxLength": 300, "description": "Optional subtitle or brief summary" }, "slug": { "type": "string", "minLength": 1, "maxLength": 256, "description": "URL-friendly identifier for the post; accessible at paragraph.com/@[publicationSlug]/[slug]" }, "staticHtml": { "type": "string", "description": "Rendered HTML content of the post" }, "json": { "type": "string", "description": "TipTap JSON representation of the post content structure. This is the source of truth that the staticHtml and markdown is generated from" }, "markdown": { "type": "string", "description": "Markdown source of the post content" }, "coinId": { "type": "string", "description": "ID of the associated coin, if the post is coined" }, "categories": { "type": "array", "items": { "type": "string" }, "description": "Categories/tags associated with this post" }, "authors": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the user" }, "walletAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Wallet address of the user" }, "avatarUrl": { "type": "string", "format": "uri", "description": "URL to the user's avatar image" }, "publicationId": { "type": "string", "description": "ID of the publication this user belongs to" }, "name": { "type": "string", "description": "Display name of the user" }, "bio": { "type": "string", "maxLength": 500, "description": "Brief biography of the user (max 500 characters)" } }, "required": [ "id", "publicationId" ] }, "description": "Authors of this post" }, "authorIds": { "type": "array", "items": { "type": "string" }, "description": "IDs of the authors of this post" }, "views": { "type": "number", "description": "Total views. Only included when fetching your own posts via GET /v1/posts" }, "status": { "type": "string", "enum": [ "published", "draft", "scheduled", "archived" ], "description": "Current publish status. Only set on authenticated endpoints (listOwn, getById for your own post). Use this instead of publishedAt to determine publish state — publishedAt is preserved across unpublishing." } }, "required": [ "id", "title", "slug" ] } } } }, "404": { "description": "Post not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getPostByPublicationSlugAndPostSlug", "x-mint": { "mcp": { "enabled": true, "name": "get-post-by-publication-and-post-slug", "description": "Get a post using its publication slug and post slug" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Get post by publication & post slug", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst post = await api.posts.get({\n publicationSlug: \"@blog\",\n slug: \"my-first-post\"\n}).single()" } ] } }, "/v1/posts": { "post": { "description": "Create a new post in your publication. The publication is identified by the API key provided in the Authorization header.\n\n**Requirements:**\n- `title` field is required\n- Provide content as either `markdown` (converted to TipTap JSON) OR `bodyJson` (a Tiptap document for content with buttons/linked images) — exactly one is required, not both\n\n**Behavior:**\n- The post will be created as published by default. Set `status` to `\"draft\"` to create a draft instead\n- If `sendNewsletter` is true, an email will be sent to all subscribers when the post publishes\n- Set `scheduledAt` (Unix timestamp in milliseconds) to schedule first-publish for a future time. Must be in the future and at most 30 days out. Scheduling cannot be combined with `status: \"draft\"`. When scheduled, the response `status` is `\"scheduled\"` and the post publishes (plus sends newsletter, if requested) at the scheduled time.", "summary": "Create a new post", "tags": [ "posts" ], "parameters": [], "requestBody": { "description": "Body", "content": { "application/json": { "schema": { "type": "object", "properties": { "markdown": { "type": "string", "description": "Post content in Markdown format. Provide `markdown` OR `bodyJson`, not both. Markdown cannot represent buttons or linked images — use `bodyJson` for those." }, "bodyJson": { "type": "string", "description": "Post content as a Tiptap document, JSON-stringified (e.g. '{\"type\":\"doc\",\"content\":[...]}'). Use instead of `markdown` when the body needs Subscribe/Share/custom buttons or linked images. Validated server-side; an invalid document is rejected. Provide `markdown` OR `bodyJson`, not both." }, "title": { "type": "string", "maxLength": 200, "description": "Title of the post" }, "subtitle": { "type": "string", "maxLength": 300, "description": "Optional subtitle or brief summary" }, "imageUrl": { "type": "string", "format": "uri", "description": "Optional URL to the post's cover image" }, "sendNewsletter": { "oneOf": [ { "type": "boolean" }, { "type": "string", "enum": [ "true", "false", "1", "0" ] } ], "description": "Whether to send an email newsletter to subscribers. Default: false" }, "status": { "type": "string", "enum": [ "published", "draft" ], "description": "Status of the post. Default: published" }, "slug": { "type": "string", "minLength": 1, "maxLength": 256, "description": "Optional URL-friendly identifier for the post. If not provided, will be generated from title" }, "postPreview": { "type": "string", "maxLength": 500, "description": "Optional preview text for the post. If not provided, will be generated from content" }, "categories": { "oneOf": [ { "type": "array", "items": { "type": "string" } }, { "type": "string" } ], "description": "Optional array of category tags for the post. Can also be a comma-separated string." }, "authorIds": { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 20, "description": "Optional user ids to credit as the post's authors, in byline order. Each id must be the publication's owner or an active team member — ids from outside the publication are rejected. Defaults to the API key's own user." }, "scheduledAt": { "description": "Optional Unix timestamp (milliseconds) to schedule first-publish of the post at a future time. Must be in the future. Cannot be combined with status: 'draft'. When set, the post is created and queued to publish (and send newsletter, if requested) at the specified time. Pass 0 or omit the field for an unscheduled post.", "type": "integer", "minimum": 0 } }, "required": [ "title" ] } } } }, "responses": { "200": { "description": "Post created successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string", "description": "The ID of the created post" }, "status": { "type": "string", "enum": [ "published", "draft", "scheduled" ], "description": "Final status of the post: 'published' if published immediately, 'draft' if created as a draft, 'scheduled' if queued to publish at scheduledAt" } }, "required": [ "id", "status" ] } } } }, "400": { "description": "Invalid request - check required fields", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "404": { "description": "Publication not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "createPost", "x-mint": { "mcp": { "enabled": true, "name": "create-post", "description": "Create a new post in a publication" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Create and publish a post", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nconst { id, status } = await api.posts.create({\n title: \"My First Post\",\n markdown: \"# Hello World\\n\\nThis is my first post!\",\n sendNewsletter: true\n})\n// status: \"published\"" }, { "lang": "typescript", "label": "Create a draft", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nconst { id, status } = await api.posts.create({\n title: \"Work in Progress\",\n markdown: \"# Draft\\n\\nStill working on this.\",\n status: \"draft\"\n})\n// status: \"draft\"" }, { "lang": "typescript", "label": "Schedule a post for a future time", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nconst { id, status } = await api.posts.create({\n title: \"Launch Announcement\",\n markdown: \"# We're launching tomorrow!\",\n scheduledAt: Date.now() + 24 * 60 * 60 * 1000,\n sendNewsletter: true,\n})\n// status: \"scheduled\"" }, { "lang": "bash", "label": "Create post using curl", "source": "curl -X POST \"https://public.api.paragraph.com/api/v1/posts\" \\\n -H \"Authorization: Bearer your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"title\": \"My First Post\", \"markdown\": \"# Hello World\"}'" } ], "security": [ { "apiKey": [] } ] }, "get": { "description": "Retrieve a paginated list of posts from your publication. The publication is identified by the API key provided in the Authorization header.\n\nUse the `status` parameter to filter by post status (published, draft, scheduled, or archived). Defaults to published.", "summary": "List your posts", "tags": [ "posts" ], "parameters": [ { "name": "cursor", "in": "query", "description": "Cursor for pagination", "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of items to return (1-100, default: 10)", "schema": { "default": 10, "type": "integer", "minimum": 1, "maximum": 100 } }, { "name": "includeContent", "in": "query", "description": "Include full content fields (markdown, json, staticHtml). Default: false", "schema": { "oneOf": [ { "type": "boolean" }, { "type": "string" } ] } }, { "name": "status", "in": "query", "description": "Filter by post status. Default: published", "schema": { "type": "string", "enum": [ "published", "draft", "scheduled", "archived" ] } } ], "responses": { "200": { "description": "Posts retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "items": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the post" }, "title": { "type": "string", "maxLength": 200, "description": "Title of the post" }, "imageUrl": { "type": "string", "format": "uri", "description": "Optional URL to the post's main image" }, "publishedAt": { "type": "string", "description": "Epoch timestamp when the post was published" }, "updatedAt": { "type": "string", "description": "Epoch timestamp when the post was last updated" }, "subtitle": { "type": "string", "maxLength": 300, "description": "Optional subtitle or brief summary" }, "slug": { "type": "string", "minLength": 1, "maxLength": 256, "description": "URL-friendly identifier for the post; accessible at paragraph.com/@[publicationSlug]/[slug]" }, "staticHtml": { "type": "string", "description": "Rendered HTML content of the post" }, "json": { "type": "string", "description": "TipTap JSON representation of the post content structure. This is the source of truth that the staticHtml and markdown is generated from" }, "markdown": { "type": "string", "description": "Markdown source of the post content" }, "coinId": { "type": "string", "description": "ID of the associated coin, if the post is coined" }, "categories": { "type": "array", "items": { "type": "string" }, "description": "Categories/tags associated with this post" }, "authors": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the user" }, "walletAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Wallet address of the user" }, "avatarUrl": { "type": "string", "format": "uri", "description": "URL to the user's avatar image" }, "publicationId": { "type": "string", "description": "ID of the publication this user belongs to" }, "name": { "type": "string", "description": "Display name of the user" }, "bio": { "type": "string", "maxLength": 500, "description": "Brief biography of the user (max 500 characters)" } }, "required": [ "id", "publicationId" ] }, "description": "Authors of this post" }, "authorIds": { "type": "array", "items": { "type": "string" }, "description": "IDs of the authors of this post" }, "views": { "type": "number", "description": "Total views. Only included when fetching your own posts via GET /v1/posts" }, "status": { "type": "string", "enum": [ "published", "draft", "scheduled", "archived" ], "description": "Current publish status. Only set on authenticated endpoints (listOwn, getById for your own post). Use this instead of publishedAt to determine publish state — publishedAt is preserved across unpublishing." } }, "required": [ "id", "title", "slug" ] }, "description": "Array of items in this page" }, "pagination": { "type": "object", "properties": { "cursor": { "type": "string", "description": "Cursor for fetching the next page of results" }, "hasMore": { "type": "boolean", "description": "Whether more results are available" }, "total": { "type": "number", "description": "Total number of items available" } }, "required": [ "hasMore" ] } }, "required": [ "items", "pagination" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "listOwnPosts", "x-mint": { "mcp": { "enabled": true, "name": "list-own-posts", "description": "List posts from your publication, filterable by status" } }, "x-codeSamples": [ { "lang": "typescript", "label": "List draft posts", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nconst { items: drafts, pagination } = await api.posts.list({ status: \"draft\" })" }, { "lang": "bash", "label": "List draft posts using curl", "source": "curl \"https://public.api.paragraph.com/api/v1/posts?status=draft\" \\\n -H \"Authorization: Bearer your-api-key\"" } ], "security": [ { "apiKey": [] } ] } }, "/v1/posts/slug/{slug}": { "put": { "description": "Update an existing post using its URL slug. The publication is identified by the API key provided in the Authorization header.\n\n**Behavior:**\n- Only provided fields are updated; omitted fields remain unchanged\n- When `markdown` is provided, it replaces the full content. Rich blocks (embeds, buttons, callouts) created in the editor will be lost\n- Set `status` to `\"published\"` to publish a draft, `\"draft\"` to unpublish, or `\"archived\"` to archive\n- When editing an already-live post that should remain live, include `status: \"published\"` in the update and verify the returned post status before telling the writer it is live\n- Set `scheduledAt` (Unix timestamp in milliseconds) to schedule a draft's first-publish for a future time. Must be in the future and at most 30 days out. Only valid for posts that haven't been published or already scheduled. Pass `scheduledAt: null` to cancel a previously scheduled publish (or to reschedule: cancel first, then schedule again with the new time). Set `sendNewsletter: true` alongside `scheduledAt` to email subscribers when the post publishes.\n- Set `imageUrl` to update the post's cover/hero image; the URL is fetched, re-hosted, and a placeholder is generated. Pass `clearImage: true` to remove the existing cover.", "summary": "Update a post by slug", "tags": [ "posts" ], "parameters": [ { "name": "slug", "in": "path", "required": true, "schema": { "type": "string", "minLength": 1, "maxLength": 256 }, "description": "URL-friendly identifier of the post to update" } ], "requestBody": { "description": "Body", "content": { "application/json": { "schema": { "type": "object", "properties": { "markdown": { "type": "string", "description": "Post content in Markdown format. Replaces the FULL body. Markdown cannot represent buttons, linked images, or embedded media (videos, tweets, link cards) — replacing a post that has any of those with `markdown` drops them. Use `bodyJson` (round-tripped from get-post) to edit an existing post so nothing is lost. Provide `markdown` OR `bodyJson`, not both." }, "bodyJson": { "type": "string", "description": "Post content as a Tiptap document, JSON-stringified (e.g. '{\"type\":\"doc\",\"content\":[...]}'). This accepts ANY Tiptap node the editor supports — including videos, tweets, link cards, callouts, and buttons — so editing a post by round-tripping the `json` returned by get-post preserves everything markdown would drop. Replaces the FULL body; node-type validity is checked by the renderer and an unusable document is rejected. Provide `markdown` OR `bodyJson`, not both." }, "title": { "type": "string", "maxLength": 200, "description": "Title of the post" }, "subtitle": { "type": "string", "maxLength": 300, "description": "Optional subtitle or brief summary" }, "slug": { "type": "string", "minLength": 1, "maxLength": 256, "description": "URL-friendly identifier for the post" }, "postPreview": { "type": "string", "maxLength": 500, "description": "Preview text for the post" }, "categories": { "oneOf": [ { "type": "array", "items": { "type": "string" } }, { "type": "string" } ], "description": "Category tags for the post. Can also be a comma-separated string." }, "authorIds": { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 20, "description": "User ids credited as the post's authors, in byline order. Replaces the full list, so include every author you want kept — read the post's current `authorIds` first and start from those. Each id must be the publication's owner or an active team member; ids from outside the publication are rejected. There is no endpoint that enumerates members, so an id has to come from a post you have read (`authorIds` on a single post, or `authors[].id` on a list) or from the writer." }, "status": { "type": "string", "enum": [ "draft", "published", "archived" ], "description": "Set to 'published' to publish a draft or keep an already-live post published after edits, 'draft' to unpublish, or 'archived' to archive" }, "scheduledAt": { "description": "Unix timestamp (milliseconds) to schedule the post's first publish at a future time. Must be in the future and at most 30 days out. Only valid for draft posts that haven't been published or already scheduled. Cannot be combined with status: 'draft' or 'archived'. Pass null to cancel a previously scheduled publish. The value 0 is treated the same as omitting the field (no scheduling request); note that on an already-scheduled post, omitting `scheduledAt` while changing `status` cancels the schedule.", "type": [ "integer", "null" ], "minimum": 0 }, "sendNewsletter": { "oneOf": [ { "type": "boolean" }, { "type": "string", "enum": [ "true", "false", "1", "0" ] } ], "description": "Whether to send an email newsletter to subscribers when the post publishes. Only meaningful when publishing (status: 'published') or scheduling (scheduledAt set). Default: false" }, "publishedAt": { "type": "integer", "minimum": 0, "exclusiveMinimum": 0, "description": "Unix timestamp (milliseconds) to set as the post's publish date. Once set, the date is preserved across re-publishes." }, "imageUrl": { "type": "string", "format": "uri", "description": "URL of an image to set as the post's cover/hero image. The image is fetched, re-hosted on Paragraph's CDN, and a placeholder is generated. Pass clearImage: true instead to remove the existing cover." }, "clearImage": { "type": "boolean", "description": "When true, removes the post's existing cover/hero image. Ignored if imageUrl is also provided." } } } } } }, "responses": { "200": { "description": "Post updated successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ true ], "description": "Whether the update succeeded" } }, "required": [ "success" ] } } } }, "400": { "description": "Invalid request - check field values", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "404": { "description": "Post not found in your publication", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "409": { "description": "Conflict - the body change was refused because you weren't working from the post's current content: either you didn't call get-post before replacing the body, or the writer edited the post in the editor since you read it. Call get-post to read the current version, re-apply your change on it, and retry.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "updatePostBySlug", "x-mint": { "mcp": { "enabled": true, "name": "update-post-by-slug", "description": "Update an existing post by its URL slug" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Update a post by slug", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nawait api.posts.update({\n slug: \"my-first-post\",\n title: \"Updated Title\",\n markdown: \"## New content\"\n})" } ], "security": [ { "apiKey": [] } ] }, "delete": { "description": "Permanently delete a post using its URL slug. The publication is identified by the API key provided in the Authorization header.\n\n**Warning:** This action is irreversible. The post and all related data (notifications and drafts) will be permanently deleted.", "summary": "Delete a post by slug", "tags": [ "posts" ], "parameters": [ { "name": "slug", "in": "path", "required": true, "schema": { "type": "string", "minLength": 1, "maxLength": 256 }, "description": "URL-friendly identifier of the post to delete" } ], "requestBody": { "description": "Body", "content": { "application/json": { "schema": { "type": "object", "properties": {} } } } }, "responses": { "200": { "description": "Post deleted successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ true ], "description": "Whether the deletion succeeded" } }, "required": [ "success" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "404": { "description": "Post not found in your publication", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "deletePostBySlug", "x-mint": { "mcp": { "enabled": true, "name": "delete-post-by-slug", "description": "Permanently delete a post by its URL slug" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Delete a post by slug", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nawait api.posts.delete({ slug: \"my-first-post\" })" } ], "security": [ { "apiKey": [] } ] } }, "/v1/posts/{postId}/test-email": { "post": { "description": "Sends a test newsletter email for the specified draft post to the publication owner's email address. Useful for previewing how a post will look as a newsletter before publishing. Only works for draft posts.", "summary": "Send a test newsletter email", "tags": [ "posts" ], "parameters": [ { "name": "postId", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Unique identifier of the post to preview" } ], "requestBody": { "description": "Body", "content": { "application/json": { "schema": { "type": "object", "properties": {} } } } }, "responses": { "200": { "description": "Test email sent successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ true ], "description": "Whether the email was sent" } }, "required": [ "success" ] } } } }, "400": { "description": "No email associated with the account", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "404": { "description": "Post not found in your publication", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "sendTestEmail", "x-mint": { "mcp": { "enabled": true, "name": "send-test-email", "description": "Send a test newsletter email for a post" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Send a test email", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nawait api.posts.sendTestEmail({ id: \"3T2PQZlsdQtigUp4fhlb\" })" }, { "lang": "bash", "label": "Send test email using curl", "source": "curl -X POST \"https://public.api.paragraph.com/api/v1/posts/3T2PQZlsdQtigUp4fhlb/test-email\" \\\n -H \"Authorization: Bearer your-api-key\"" } ], "security": [ { "apiKey": [] } ] } }, "/v1/content": { "post": { "description": "Save a finished piece of short-form content — an X post or thread, a LinkedIn post, a one-off email, or an X Article — to your publication's library.\n\n**What this does:**\n- The piece is saved as a draft and shows up in the Paragraph app under Content, where you can edit it and send it.\n- Nothing is posted, emailed, or scheduled. Sending happens in the app, so a draft you upload can't go out without you.\n- Long-form Paragraph posts are a different resource — use `POST /v1/posts` for those.\n\n**The body:**\n- `body` carries the artifact itself, in the shape its kind uses (see the field descriptions below).\n- It's validated the same way the Paragraph app validates it, so an X thread over 280 characters an entry, or an Article missing its headline, comes back with the same explanation you'd see in the app.\n- Drafts created here are text-only. Media has to be uploaded to X or LinkedIn first, which the API can't do yet.", "summary": "Create a draft", "tags": [ "content" ], "parameters": [], "requestBody": { "description": "Body", "content": { "application/json": { "schema": { "type": "object", "properties": { "kind": { "type": "string", "enum": [ "tweet", "linkedin", "newsletter", "x_article" ], "description": "What kind of piece this is" }, "title": { "type": "string", "minLength": 1, "maxLength": 200, "description": "What this piece is called in your library. Sentence case, no trailing period. Not published anywhere — for an X Article headline, use `body.title`." }, "body": { "type": "object", "properties": { "text": { "type": "string", "description": "The post's text. `tweet`: a single tweet, at most 280 characters — use `tweets` for a thread and never send both. `linkedin`: the post body." }, "tweets": { "type": "array", "items": { "type": "string" }, "description": "`tweet` only. One entry per tweet, in posting order, each at most 280 characters. Never concatenate a thread into one entry." }, "subject": { "type": "string", "description": "`newsletter` only. Subject line." }, "preheader": { "type": "string", "description": "`newsletter` only. Optional preview line shown after the subject." }, "body": { "type": "string", "description": "`newsletter`: the email body. `x_article`: the article's full CommonMark markdown." }, "title": { "type": "string", "description": "`x_article` only. The headline as published on X. Separate from the piece's `title`, which only names it in your library." }, "canonicalUrl": { "type": "string", "description": "`x_article` only. The original post this Article is a version of. It must also appear as a markdown link inside `body`." }, "media": { "readOnly": true, "description": "Not accepted. Media has to be uploaded to the destination platform first, which the API can't do yet; sending this field is rejected." } }, "additionalProperties": false, "description": "The artifact itself, in the shape this kind uses" } }, "required": [ "kind", "title", "body" ] } } } }, "responses": { "200": { "description": "Draft created successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for this piece of content" }, "kind": { "type": "string", "description": "What this piece is: `tweet`, `linkedin`, `newsletter`, or `x_article`" }, "title": { "type": "string", "description": "What this piece is called in your library" }, "excerpt": { "type": "string", "description": "First readable line of the body, for listing views" }, "status": { "type": "string", "enum": [ "draft", "published", "archived" ], "description": "Whether this piece has been delivered, is still a draft, or was archived" }, "scheduled": { "type": "boolean", "description": "Whether a scheduled send is queued against this piece" }, "lockedReason": { "type": [ "string", "null" ], "description": "Why this piece can't be edited right now, or null when it can. A queued or in-flight send locks the words, because they go out exactly as written." }, "publishedAt": { "type": [ "string", "null" ], "description": "ISO 8601 timestamp of the first delivery, or null" }, "url": { "type": [ "string", "null" ], "description": "Where this piece went live, from the same delivery `publishedAt` came from. Null when it hasn't been delivered, and null by design for a channel that publishes no page: a custom email renders into the message itself, so there is no address to link to. Never guessed — a delivery whose id isn't shaped like its channel reports null rather than a link that would 404." }, "archivedAt": { "type": [ "string", "null" ], "description": "ISO 8601 timestamp of when this piece was archived, or null" }, "createdAt": { "type": "string", "description": "ISO 8601 timestamp of creation" }, "updatedAt": { "type": "string", "description": "ISO 8601 timestamp of the last change" }, "body": { "type": "object", "additionalProperties": {}, "description": "The artifact itself, in the shape its kind uses" } }, "required": [ "id", "kind", "title", "excerpt", "status", "scheduled", "lockedReason", "publishedAt", "url", "archivedAt", "createdAt", "updatedAt", "body" ] } } } }, "400": { "description": "The draft is missing content or doesn't match its kind", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "404": { "description": "Publication not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "createContent", "x-mint": { "mcp": { "enabled": true, "name": "create-content", "description": "Save an X post, LinkedIn post, newsletter, or X Article as a draft in a publication's library" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Draft an X thread", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nconst draft = await api.content.create({\n kind: \"tweet\",\n title: \"Thread on writing in public\",\n body: { tweets: [\"Writing in public changes what you write.\", \"Here's what changed for me.\"] },\n})" }, { "lang": "typescript", "label": "Draft a newsletter", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nconst draft = await api.content.create({\n kind: \"newsletter\",\n title: \"October update\",\n body: { subject: \"What we shipped in October\", body: \"Hi everyone,\" },\n})" }, { "lang": "bash", "label": "Draft a LinkedIn post using curl", "source": "curl -X POST \"https://public.api.paragraph.com/api/v1/content\" \\\n -H \"Authorization: Bearer your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"kind\":\"linkedin\",\"title\":\"Launch note\",\"body\":{\"text\":\"We shipped it.\"}}'" } ], "security": [ { "apiKey": [] } ] }, "get": { "description": "Retrieve a paginated list of the short-form content in your publication's library, newest activity first. The publication is identified by the API key.\n\nFilter with `kind` and `status`. `status` defaults to `all`, which is everything except the pieces you've archived — a piece that was delivered stays listed whether or not it was archived afterwards.\n\nBodies aren't included; fetch a single piece to read one.", "summary": "List your drafted content", "tags": [ "content" ], "parameters": [ { "name": "cursor", "in": "query", "description": "Cursor for pagination", "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of items to return (1-50, default: 20)", "schema": { "default": 20, "type": "integer", "minimum": 1, "maximum": 50 } }, { "name": "kind", "in": "query", "description": "Filter by content kind", "schema": { "type": "string", "enum": [ "tweet", "linkedin", "newsletter", "x_article" ] } }, { "name": "status", "in": "query", "description": "Filter by lifecycle. `all` (default) is drafts plus delivered pieces; `archived` is the pieces you've put away and never delivered.", "schema": { "type": "string", "enum": [ "all", "draft", "published", "archived" ] } } ], "responses": { "200": { "description": "Content retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "items": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for this piece of content" }, "kind": { "type": "string", "description": "What this piece is: `tweet`, `linkedin`, `newsletter`, or `x_article`" }, "title": { "type": "string", "description": "What this piece is called in your library" }, "excerpt": { "type": "string", "description": "First readable line of the body, for listing views" }, "status": { "type": "string", "enum": [ "draft", "published", "archived" ], "description": "Whether this piece has been delivered, is still a draft, or was archived" }, "scheduled": { "type": "boolean", "description": "Whether a scheduled send is queued against this piece" }, "lockedReason": { "type": [ "string", "null" ], "description": "Why this piece can't be edited right now, or null when it can. A queued or in-flight send locks the words, because they go out exactly as written." }, "publishedAt": { "type": [ "string", "null" ], "description": "ISO 8601 timestamp of the first delivery, or null" }, "url": { "type": [ "string", "null" ], "description": "Where this piece went live, from the same delivery `publishedAt` came from. Null when it hasn't been delivered, and null by design for a channel that publishes no page: a custom email renders into the message itself, so there is no address to link to. Never guessed — a delivery whose id isn't shaped like its channel reports null rather than a link that would 404." }, "archivedAt": { "type": [ "string", "null" ], "description": "ISO 8601 timestamp of when this piece was archived, or null" }, "createdAt": { "type": "string", "description": "ISO 8601 timestamp of creation" }, "updatedAt": { "type": "string", "description": "ISO 8601 timestamp of the last change" } }, "required": [ "id", "kind", "title", "excerpt", "status", "scheduled", "lockedReason", "publishedAt", "url", "archivedAt", "createdAt", "updatedAt" ] }, "description": "Array of items in this page" }, "pagination": { "type": "object", "properties": { "cursor": { "type": "string", "description": "Cursor for fetching the next page of results" }, "hasMore": { "type": "boolean", "description": "Whether more results are available" }, "total": { "type": "number", "description": "Total number of items available" } }, "required": [ "hasMore" ] } }, "required": [ "items", "pagination" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "404": { "description": "Publication not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "listContent", "x-mint": { "mcp": { "enabled": true, "name": "list-content", "description": "List drafted content in a publication's library, filterable by kind and status" } }, "x-codeSamples": [ { "lang": "typescript", "label": "List drafted X posts", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nconst { items, pagination } = await api.content.list({ kind: \"tweet\", status: \"draft\" })" }, { "lang": "bash", "label": "List drafted X posts using curl", "source": "curl \"https://public.api.paragraph.com/api/v1/content?kind=tweet&status=draft\" \\\n -H \"Authorization: Bearer your-api-key\"" } ], "security": [ { "apiKey": [] } ] } }, "/v1/content/{contentId}": { "get": { "description": "Retrieve one piece of drafted content with its body. Read it before editing so you rewrite what's actually saved — the draft may have changed in the app.", "summary": "Get a piece of content", "tags": [ "content" ], "parameters": [ { "name": "contentId", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Unique identifier of the content" } ], "responses": { "200": { "description": "Content retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for this piece of content" }, "kind": { "type": "string", "description": "What this piece is: `tweet`, `linkedin`, `newsletter`, or `x_article`" }, "title": { "type": "string", "description": "What this piece is called in your library" }, "excerpt": { "type": "string", "description": "First readable line of the body, for listing views" }, "status": { "type": "string", "enum": [ "draft", "published", "archived" ], "description": "Whether this piece has been delivered, is still a draft, or was archived" }, "scheduled": { "type": "boolean", "description": "Whether a scheduled send is queued against this piece" }, "lockedReason": { "type": [ "string", "null" ], "description": "Why this piece can't be edited right now, or null when it can. A queued or in-flight send locks the words, because they go out exactly as written." }, "publishedAt": { "type": [ "string", "null" ], "description": "ISO 8601 timestamp of the first delivery, or null" }, "url": { "type": [ "string", "null" ], "description": "Where this piece went live, from the same delivery `publishedAt` came from. Null when it hasn't been delivered, and null by design for a channel that publishes no page: a custom email renders into the message itself, so there is no address to link to. Never guessed — a delivery whose id isn't shaped like its channel reports null rather than a link that would 404." }, "archivedAt": { "type": [ "string", "null" ], "description": "ISO 8601 timestamp of when this piece was archived, or null" }, "createdAt": { "type": "string", "description": "ISO 8601 timestamp of creation" }, "updatedAt": { "type": "string", "description": "ISO 8601 timestamp of the last change" }, "body": { "type": "object", "additionalProperties": {}, "description": "The artifact itself, in the shape its kind uses" } }, "required": [ "id", "kind", "title", "excerpt", "status", "scheduled", "lockedReason", "publishedAt", "url", "archivedAt", "createdAt", "updatedAt", "body" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "404": { "description": "Content not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getContentById", "x-mint": { "mcp": { "enabled": true, "name": "get-content", "description": "Get one piece of drafted content, with its body" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Get a piece of content", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nconst draft = await api.content.get({ id: \"7f3a2c18-5b9e-4c21-9a0d-8e6b1f4d2a55\" })" }, { "lang": "bash", "label": "Get a piece of content using curl", "source": "curl \"https://public.api.paragraph.com/api/v1/content/7f3a2c18-5b9e-4c21-9a0d-8e6b1f4d2a55\" \\\n -H \"Authorization: Bearer your-api-key\"" } ], "security": [ { "apiKey": [] } ] }, "patch": { "description": "Rename a piece of content, replace its body, or both.\n\n**Replacement, not a merge:** `body` replaces the artifact entirely, in the same shape the kind takes on create. Send the whole thing, not just the part that changed. Media already attached to the draft is the one exception — you can't send it back, so it's carried over rather than dropped.\n\n**Scheduled pieces are locked:** if a send is queued or already running for this piece, its words go out exactly as written, so an edit to `body` is refused with an explanation. Cancel the schedule in the app first. Renaming is always allowed — a title isn't published anywhere.", "summary": "Edit a piece of content", "tags": [ "content" ], "parameters": [ { "name": "contentId", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Unique identifier of the content" } ], "requestBody": { "description": "Body", "content": { "application/json": { "schema": { "type": "object", "properties": { "title": { "type": "string", "minLength": 1, "maxLength": 200, "description": "New name for this piece in your library" }, "body": { "type": "object", "properties": { "text": { "type": "string", "description": "The post's text. `tweet`: a single tweet, at most 280 characters — use `tweets` for a thread and never send both. `linkedin`: the post body." }, "tweets": { "type": "array", "items": { "type": "string" }, "description": "`tweet` only. One entry per tweet, in posting order, each at most 280 characters. Never concatenate a thread into one entry." }, "subject": { "type": "string", "description": "`newsletter` only. Subject line." }, "preheader": { "type": "string", "description": "`newsletter` only. Optional preview line shown after the subject." }, "body": { "type": "string", "description": "`newsletter`: the email body. `x_article`: the article's full CommonMark markdown." }, "title": { "type": "string", "description": "`x_article` only. The headline as published on X. Separate from the piece's `title`, which only names it in your library." }, "canonicalUrl": { "type": "string", "description": "`x_article` only. The original post this Article is a version of. It must also appear as a markdown link inside `body`." }, "media": { "readOnly": true, "description": "Not accepted. Media has to be uploaded to the destination platform first, which the API can't do yet; sending this field is rejected." } }, "additionalProperties": false, "description": "The replacement artifact, in the shape this piece's kind uses" } }, "additionalProperties": false } } } }, "responses": { "200": { "description": "Content updated successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for this piece of content" }, "kind": { "type": "string", "description": "What this piece is: `tweet`, `linkedin`, `newsletter`, or `x_article`" }, "title": { "type": "string", "description": "What this piece is called in your library" }, "excerpt": { "type": "string", "description": "First readable line of the body, for listing views" }, "status": { "type": "string", "enum": [ "draft", "published", "archived" ], "description": "Whether this piece has been delivered, is still a draft, or was archived" }, "scheduled": { "type": "boolean", "description": "Whether a scheduled send is queued against this piece" }, "lockedReason": { "type": [ "string", "null" ], "description": "Why this piece can't be edited right now, or null when it can. A queued or in-flight send locks the words, because they go out exactly as written." }, "publishedAt": { "type": [ "string", "null" ], "description": "ISO 8601 timestamp of the first delivery, or null" }, "url": { "type": [ "string", "null" ], "description": "Where this piece went live, from the same delivery `publishedAt` came from. Null when it hasn't been delivered, and null by design for a channel that publishes no page: a custom email renders into the message itself, so there is no address to link to. Never guessed — a delivery whose id isn't shaped like its channel reports null rather than a link that would 404." }, "archivedAt": { "type": [ "string", "null" ], "description": "ISO 8601 timestamp of when this piece was archived, or null" }, "createdAt": { "type": "string", "description": "ISO 8601 timestamp of creation" }, "updatedAt": { "type": "string", "description": "ISO 8601 timestamp of the last change" }, "body": { "type": "object", "additionalProperties": {}, "description": "The artifact itself, in the shape its kind uses" } }, "required": [ "id", "kind", "title", "excerpt", "status", "scheduled", "lockedReason", "publishedAt", "url", "archivedAt", "createdAt", "updatedAt", "body" ] } } } }, "400": { "description": "The draft doesn't match its kind, or a queued send has locked it", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "404": { "description": "Content not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "updateContent", "x-mint": { "mcp": { "enabled": true, "name": "update-content", "description": "Edit a piece of drafted content in place, replacing its body or renaming it" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Rewrite a draft", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nconst draft = await api.content.update({\n id: \"7f3a2c18-5b9e-4c21-9a0d-8e6b1f4d2a55\",\n body: { text: \"Rewritten, and shorter.\" },\n})" }, { "lang": "bash", "label": "Rename a draft using curl", "source": "curl -X PATCH \"https://public.api.paragraph.com/api/v1/content/7f3a2c18-5b9e-4c21-9a0d-8e6b1f4d2a55\" \\\n -H \"Authorization: Bearer your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"title\": \"Launch note, second pass\"}'" } ], "security": [ { "apiKey": [] } ] } }, "/v1/content/{contentId}/archive": { "post": { "description": "Put a piece away without deleting it. Archived content drops out of the default list and out of the writer's Content surface, and `POST /v1/content/{contentId}/restore` brings it back.\n\nAny suggestion still proposing the piece is dismissed along with it, so nothing is left offering to send something you've filed away. A piece with a send already queued can't be archived — cancel the schedule first.", "summary": "Archive a piece of content", "tags": [ "content" ], "parameters": [ { "name": "contentId", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Unique identifier of the content" } ], "requestBody": { "description": "Body", "content": { "application/json": { "schema": { "type": "object", "properties": {} } } } }, "responses": { "200": { "description": "Content archived successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for this piece of content" }, "kind": { "type": "string", "description": "What this piece is: `tweet`, `linkedin`, `newsletter`, or `x_article`" }, "title": { "type": "string", "description": "What this piece is called in your library" }, "excerpt": { "type": "string", "description": "First readable line of the body, for listing views" }, "status": { "type": "string", "enum": [ "draft", "published", "archived" ], "description": "Whether this piece has been delivered, is still a draft, or was archived" }, "scheduled": { "type": "boolean", "description": "Whether a scheduled send is queued against this piece" }, "lockedReason": { "type": [ "string", "null" ], "description": "Why this piece can't be edited right now, or null when it can. A queued or in-flight send locks the words, because they go out exactly as written." }, "publishedAt": { "type": [ "string", "null" ], "description": "ISO 8601 timestamp of the first delivery, or null" }, "url": { "type": [ "string", "null" ], "description": "Where this piece went live, from the same delivery `publishedAt` came from. Null when it hasn't been delivered, and null by design for a channel that publishes no page: a custom email renders into the message itself, so there is no address to link to. Never guessed — a delivery whose id isn't shaped like its channel reports null rather than a link that would 404." }, "archivedAt": { "type": [ "string", "null" ], "description": "ISO 8601 timestamp of when this piece was archived, or null" }, "createdAt": { "type": "string", "description": "ISO 8601 timestamp of creation" }, "updatedAt": { "type": "string", "description": "ISO 8601 timestamp of the last change" }, "body": { "type": "object", "additionalProperties": {}, "description": "The artifact itself, in the shape its kind uses" } }, "required": [ "id", "kind", "title", "excerpt", "status", "scheduled", "lockedReason", "publishedAt", "url", "archivedAt", "createdAt", "updatedAt", "body" ] } } } }, "400": { "description": "A queued send is blocking this", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "404": { "description": "Content not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "archiveContent", "x-mint": { "mcp": { "enabled": true, "name": "archive-content", "description": "Archive a piece of drafted content" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Archive a draft", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nawait api.content.archive({ id: \"7f3a2c18-5b9e-4c21-9a0d-8e6b1f4d2a55\" })" }, { "lang": "bash", "label": "Archive a draft using curl", "source": "curl -X POST \"https://public.api.paragraph.com/api/v1/content/7f3a2c18-5b9e-4c21-9a0d-8e6b1f4d2a55/archive\" \\\n -H \"Authorization: Bearer your-api-key\"" } ], "security": [ { "apiKey": [] } ] } }, "/v1/content/{contentId}/restore": { "post": { "description": "Bring an archived piece back into your library. Suggestions dismissed when it was archived stay dismissed — you get the draft back, not the to-do items telling you to ship it.", "summary": "Restore an archived piece", "tags": [ "content" ], "parameters": [ { "name": "contentId", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Unique identifier of the content" } ], "requestBody": { "description": "Body", "content": { "application/json": { "schema": { "type": "object", "properties": {} } } } }, "responses": { "200": { "description": "Content restored successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for this piece of content" }, "kind": { "type": "string", "description": "What this piece is: `tweet`, `linkedin`, `newsletter`, or `x_article`" }, "title": { "type": "string", "description": "What this piece is called in your library" }, "excerpt": { "type": "string", "description": "First readable line of the body, for listing views" }, "status": { "type": "string", "enum": [ "draft", "published", "archived" ], "description": "Whether this piece has been delivered, is still a draft, or was archived" }, "scheduled": { "type": "boolean", "description": "Whether a scheduled send is queued against this piece" }, "lockedReason": { "type": [ "string", "null" ], "description": "Why this piece can't be edited right now, or null when it can. A queued or in-flight send locks the words, because they go out exactly as written." }, "publishedAt": { "type": [ "string", "null" ], "description": "ISO 8601 timestamp of the first delivery, or null" }, "url": { "type": [ "string", "null" ], "description": "Where this piece went live, from the same delivery `publishedAt` came from. Null when it hasn't been delivered, and null by design for a channel that publishes no page: a custom email renders into the message itself, so there is no address to link to. Never guessed — a delivery whose id isn't shaped like its channel reports null rather than a link that would 404." }, "archivedAt": { "type": [ "string", "null" ], "description": "ISO 8601 timestamp of when this piece was archived, or null" }, "createdAt": { "type": "string", "description": "ISO 8601 timestamp of creation" }, "updatedAt": { "type": "string", "description": "ISO 8601 timestamp of the last change" }, "body": { "type": "object", "additionalProperties": {}, "description": "The artifact itself, in the shape its kind uses" } }, "required": [ "id", "kind", "title", "excerpt", "status", "scheduled", "lockedReason", "publishedAt", "url", "archivedAt", "createdAt", "updatedAt", "body" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "404": { "description": "Content not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "restoreContent", "x-mint": { "mcp": { "enabled": true, "name": "restore-content", "description": "Restore an archived piece of drafted content" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Restore an archived draft", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nawait api.content.restore({ id: \"7f3a2c18-5b9e-4c21-9a0d-8e6b1f4d2a55\" })" }, { "lang": "bash", "label": "Restore an archived draft using curl", "source": "curl -X POST \"https://public.api.paragraph.com/api/v1/content/7f3a2c18-5b9e-4c21-9a0d-8e6b1f4d2a55/restore\" \\\n -H \"Authorization: Bearer your-api-key\"" } ], "security": [ { "apiKey": [] } ] } }, "/v1/me": { "get": { "description": "Returns the publication associated with the API key used in the request. Useful for verifying your API key and retrieving your publication details.", "summary": "Get authenticated publication", "tags": [ "me" ], "parameters": [], "responses": { "200": { "description": "Authenticated publication details retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the publication" }, "name": { "type": "string", "description": "Display name of the publication" }, "ownerUserId": { "type": "string", "description": "ID of the user who owns this publication" }, "slug": { "type": "string", "minLength": 1, "maxLength": 256, "description": "URL-friendly identifier for the publication; accessible at paragraph.com/@[slug]" }, "customDomain": { "type": "string", "format": "uri", "description": "Custom domain configured for this publication" }, "summary": { "type": "string", "maxLength": 500, "description": "Brief description of the publication (max 500 characters)" }, "logoUrl": { "type": "string", "format": "uri", "description": "URL to the publication's logo image" }, "postListType": { "type": "string", "enum": [ "feed", "grid", "full-post" ], "description": "Homepage layout. 'feed' is a single-column list of cards, 'grid' is a 3-column grid, 'full-post' shows full posts in a single column." }, "themeColor": { "type": "string", "enum": [ "default", "orange-500", "rose-600", "pink-500", "fuchsia-600", "purple-600", "violet-600", "indigo-600", "blue-600", "sky-600", "cyan-600", "teal-600", "emerald-600", "green-600", "lime-600", "yellow-700", "amber-600", "orange-600", "stone-800", "rose-900", "indigo-950", "teal-950", "lime-950", "orange-950" ], "description": "Theme accent color for the publication" }, "headerFont": { "type": "string", "enum": [ "default", "serif", "mono" ], "description": "Font family used for headers" }, "bodyFont": { "type": "string", "enum": [ "default", "serif", "mono" ], "description": "Font family used for body text" }, "showMostPopular": { "type": "boolean", "description": "Whether the 'most popular posts' widget is shown" }, "hideStats": { "type": "boolean", "description": "Whether to hide stats like subscriber count, post count, and collects" }, "featuredPost": { "type": "string", "minLength": 1, "description": "Featured post selector. Use 'latest' for the most recent post, 'popular' for the most-viewed post, 'disabled' to hide the featured slot, or the ID of a specific post in this publication." }, "enableTableOfContents": { "type": "boolean", "description": "Whether the table of contents is enabled on posts" }, "enableSubscribePopup": { "type": "boolean", "description": "Whether to show the subscribe popup to first-time visitors arriving from external links" }, "enableSubscribeScroll": { "type": "boolean", "description": "Whether to show the subscribe popup when first-time visitors scroll a post" }, "pinnedPostIds": { "type": "array", "items": { "type": "string" }, "description": "Ordered list of post IDs pinned to the top of the publication's homepage. Pinned posts render in their own section above the regular feed." }, "emailNotifications": { "type": "object", "properties": { "newSubscriber": { "type": "boolean", "description": "Email the writer when a new free subscriber signs up" } }, "description": "Owner-side email notification toggles" }, "plan": { "type": "string", "enum": [ "free", "starter", "growth", "scale" ], "description": "Subscription plan of the publication. Only returned on /v1/me." } }, "required": [ "id", "name", "ownerUserId", "slug" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getMe", "x-mint": { "mcp": { "enabled": true, "name": "get-me", "description": "Get the publication associated with the authenticated API key" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Get authenticated publication", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nconst publication = await api.me.get()" }, { "lang": "bash", "label": "Get authenticated publication using curl", "source": "curl \"https://public.api.paragraph.com/api/v1/me\" \\\n -H \"Authorization: Bearer your-api-key\"" } ], "security": [ { "apiKey": [] } ] } }, "/v1/users/{userId}": { "get": { "description": "Retrieve detailed information about a specific user", "summary": "Get user by ID", "tags": [ "users" ], "parameters": [ { "name": "userId", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Unique identifier of the user" } ], "responses": { "200": { "description": "User details retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the user" }, "walletAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Wallet address of the user" }, "avatarUrl": { "type": "string", "format": "uri", "description": "URL to the user's avatar image" }, "publicationId": { "type": "string", "description": "ID of the publication this user belongs to" }, "name": { "type": "string", "description": "Display name of the user" }, "bio": { "type": "string", "maxLength": 500, "description": "Brief biography of the user (max 500 characters)" } }, "required": [ "id", "publicationId" ] } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getUser", "x-mint": { "mcp": { "enabled": true, "name": "get-user-by-id", "description": "Get detailed information about a specific user" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Get user by ID", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst user = await api.users.get({ id: \"AeAOtR8TqKWyzG5apA1R\" }).single()" } ] } }, "/v1/users/wallet/{walletAddress}": { "get": { "description": "Retrieve user details using their Ethereum wallet address", "summary": "Get user by wallet address", "tags": [ "users" ], "parameters": [ { "name": "walletAddress", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$" }, "description": "Ethereum wallet address" } ], "responses": { "200": { "description": "User details retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the user" }, "walletAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Wallet address of the user" }, "avatarUrl": { "type": "string", "format": "uri", "description": "URL to the user's avatar image" }, "publicationId": { "type": "string", "description": "ID of the publication this user belongs to" }, "name": { "type": "string", "description": "Display name of the user" }, "bio": { "type": "string", "maxLength": 500, "description": "Brief biography of the user (max 500 characters)" } }, "required": [ "id", "publicationId" ] } } } }, "404": { "description": "User not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getUserByWallet", "x-mint": { "mcp": { "enabled": true, "name": "get-user-by-wallet", "description": "Get user details using their Ethereum wallet address" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Get user by wallet address", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst user = await api.users.get({ wallet: \"0xc9ddb5E37165827BBBFf15b582E232C06862C4E8\" }).single()" } ] } }, "/v1/coins/{id}": { "get": { "description": "Retrieve information about a tokenized post using its unique ID", "summary": "Get coin by ID", "tags": [ "coins" ], "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Paragraph-internal unique identifier for the coin" } ], "responses": { "200": { "description": "Coin details retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the coin" }, "contractAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Base contract address for the coin" }, "metadata": { "type": "object", "properties": { "name": { "type": "string", "description": "Name of the coin" }, "symbol": { "type": "string", "description": "Symbol of the coin" }, "decimals": { "type": "number", "description": "Number of decimals of the coin" }, "description": { "type": "string", "description": "Description of the coin" }, "image": { "type": "string", "description": "Image url of the logo associated with the coin" }, "logoURI": { "type": "string", "description": "Image url of the logo associated with the coin" }, "chainId": { "type": "number", "description": "Chain id number of the coin" }, "external_url": { "type": "string", "description": "External url associated with the coin" }, "links": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string", "description": "Name of the link" }, "url": { "type": "string", "description": "URL of the link" } }, "required": [ "name", "url" ] } }, "tags": { "type": "array", "items": { "type": "string" }, "description": "Tags associated with the coin" }, "extensions": { "type": "object", "properties": { "coinType": { "type": "string", "description": "Type of the coin" }, "paragraph": { "type": "object", "properties": { "blogId": { "type": "string", "description": "ID of the blog associated with this coin" }, "blogUrl": { "type": "string", "description": "URL of the blog associated with this coin" }, "authorName": { "type": "string", "description": "Name of the author associated with this coin" }, "noteId": { "type": "string", "description": "ID of the note associated with this coin" }, "postSlug": { "type": "string", "description": "Slug of the post associated with this coin" } }, "required": [ "blogId", "blogUrl" ] } }, "required": [ "coinType", "paragraph" ] }, "attributes": { "type": "array", "items": { "type": "object", "properties": { "trait_type": { "type": "string" }, "value": { "type": "string" } }, "required": [ "trait_type", "value" ] } } }, "required": [ "name", "symbol", "decimals", "description", "chainId", "external_url", "links", "tags", "extensions", "attributes" ] } }, "required": [ "id", "contractAddress", "metadata" ] } } } }, "404": { "description": "Coin not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getCoin", "x-mint": { "mcp": { "enabled": true, "name": "get-coin-by-id", "description": "Get information about a coin by its ID" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Get coin by ID", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst coin = await api.coins.get({ id: \"S2AlaNG5Hw0NdNptmLTw\" }).single()" } ] } }, "/v1/coins/contract/{contractAddress}": { "get": { "description": "Retrieve information about a tokenized post using its contract address", "summary": "Get coin by contract address", "tags": [ "coins" ], "parameters": [ { "name": "contractAddress", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$" }, "description": "Contract address" } ], "responses": { "200": { "description": "Coin details retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the coin" }, "contractAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Base contract address for the coin" }, "metadata": { "type": "object", "properties": { "name": { "type": "string", "description": "Name of the coin" }, "symbol": { "type": "string", "description": "Symbol of the coin" }, "decimals": { "type": "number", "description": "Number of decimals of the coin" }, "description": { "type": "string", "description": "Description of the coin" }, "image": { "type": "string", "description": "Image url of the logo associated with the coin" }, "logoURI": { "type": "string", "description": "Image url of the logo associated with the coin" }, "chainId": { "type": "number", "description": "Chain id number of the coin" }, "external_url": { "type": "string", "description": "External url associated with the coin" }, "links": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string", "description": "Name of the link" }, "url": { "type": "string", "description": "URL of the link" } }, "required": [ "name", "url" ] } }, "tags": { "type": "array", "items": { "type": "string" }, "description": "Tags associated with the coin" }, "extensions": { "type": "object", "properties": { "coinType": { "type": "string", "description": "Type of the coin" }, "paragraph": { "type": "object", "properties": { "blogId": { "type": "string", "description": "ID of the blog associated with this coin" }, "blogUrl": { "type": "string", "description": "URL of the blog associated with this coin" }, "authorName": { "type": "string", "description": "Name of the author associated with this coin" }, "noteId": { "type": "string", "description": "ID of the note associated with this coin" }, "postSlug": { "type": "string", "description": "Slug of the post associated with this coin" } }, "required": [ "blogId", "blogUrl" ] } }, "required": [ "coinType", "paragraph" ] }, "attributes": { "type": "array", "items": { "type": "object", "properties": { "trait_type": { "type": "string" }, "value": { "type": "string" } }, "required": [ "trait_type", "value" ] } } }, "required": [ "name", "symbol", "decimals", "description", "chainId", "external_url", "links", "tags", "extensions", "attributes" ] } }, "required": [ "id", "contractAddress", "metadata" ] } } } }, "404": { "description": "Coin not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getCoinByContract", "x-mint": { "mcp": { "enabled": true, "name": "get-coin-by-contract", "description": "Get information about a coin by contract address" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Get coin by contract address", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst coin = await api.coins.get({ contract: \"0xe9bb3166ff5f96381e257d509a801303b68e5d34\" }).single()" } ] } }, "/v1/coins/{id}/holders": { "get": { "description": "Retrieve a paginated list of holders for a coined post", "summary": "List coin holders by ID", "tags": [ "coins" ], "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Unique ID of the coin" }, { "name": "cursor", "in": "query", "description": "Cursor for pagination", "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of items to return (1-100, default: 10)", "schema": { "default": 10, "type": "integer", "minimum": 1, "maximum": 100 } } ], "responses": { "200": { "description": "Holders retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "items": { "type": "array", "items": { "type": "object", "properties": { "walletAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Wallet address of the holder" }, "userId": { "type": "string", "description": "Paragraph user ID if the holder is a registered user" }, "balance": { "type": "string", "pattern": "^[0-9]+$", "description": "Token balance held (in wei)" }, "avatarUrl": { "type": "string", "format": "uri", "description": "URL to the user's avatar image, if available" } }, "required": [ "walletAddress", "balance" ] }, "description": "Array of items in this page" }, "pagination": { "type": "object", "properties": { "cursor": { "type": "string", "description": "Cursor for fetching the next page of results" }, "hasMore": { "type": "boolean", "description": "Whether more results are available" }, "total": { "type": "number", "description": "Total number of items available" } }, "required": [ "hasMore" ] } }, "required": [ "items", "pagination" ] } } } }, "404": { "description": "Coin not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getCoinHoldersById", "x-mint": { "mcp": { "enabled": true, "name": "list-coin-holders-by-id", "description": "List holders of a coined post by coin ID" } }, "x-codeSamples": [ { "lang": "typescript", "label": "List coin holders (with pagination)", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst { items: holders, pagination } = await api.coins.getHolders({ id: \"S2AlaNG5Hw0NdNptmLTw\", limit: 25 })" } ] } }, "/v1/coins/contract/{contractAddress}/holders": { "get": { "description": "Retrieve a paginated list of holders for a tokenized post", "summary": "List coin holders by contract address", "tags": [ "coins" ], "parameters": [ { "name": "contractAddress", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$" }, "description": "Contract address" }, { "name": "cursor", "in": "query", "description": "Cursor for pagination", "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of items to return (1-100, default: 10)", "schema": { "default": 10, "type": "integer", "minimum": 1, "maximum": 100 } } ], "responses": { "200": { "description": "Holders retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "items": { "type": "array", "items": { "type": "object", "properties": { "walletAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Wallet address of the holder" }, "userId": { "type": "string", "description": "Paragraph user ID if the holder is a registered user" }, "balance": { "type": "string", "pattern": "^[0-9]+$", "description": "Token balance held (in wei)" }, "avatarUrl": { "type": "string", "format": "uri", "description": "URL to the user's avatar image, if available" } }, "required": [ "walletAddress", "balance" ] }, "description": "Array of items in this page" }, "pagination": { "type": "object", "properties": { "cursor": { "type": "string", "description": "Cursor for fetching the next page of results" }, "hasMore": { "type": "boolean", "description": "Whether more results are available" }, "total": { "type": "number", "description": "Total number of items available" } }, "required": [ "hasMore" ] } }, "required": [ "items", "pagination" ] } } } }, "404": { "description": "Coin not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getCoinHoldersByContract", "x-mint": { "mcp": { "enabled": true, "name": "list-coin-holders-by-contract", "description": "List holders of a coined post by contract address" } }, "x-codeSamples": [ { "lang": "typescript", "label": "List coin holders (with pagination)", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst { items: holders, pagination } = await api.coins.getHolders({ contract: \"0xe9bb3166ff5f96381e257d509a801303b68e5d34\", limit: 50 })" } ] } }, "/v1/coins/buy/{id}": { "get": { "description": "Retrieve the args needed to buy a coin using a wallet", "summary": "Get coin's buy args by ID", "tags": [ "coins" ], "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Id of the coin" }, { "name": "walletAddress", "in": "query", "description": "Address of the wallet that is going to buy the coin", "required": true, "schema": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$" } }, { "name": "amount", "in": "query", "description": "Amount of Base ETH in wei that is going to be swapped for the coin", "required": true, "schema": { "type": "string", "pattern": "[0-9]+" } } ], "responses": { "200": { "description": "Buy args retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "commands": { "type": "string", "pattern": "^0x[a-fA-F0-9]*", "description": "Commands needed to do a token swap" }, "inputs": { "type": "array", "items": { "type": "string", "pattern": "^0x[a-fA-F0-9]*" }, "description": "Inputs needed to do a token swap" } }, "required": [ "commands", "inputs" ] } } } }, "404": { "description": "Buy args not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getBuyArgsById", "x-mint": { "mcp": { "enabled": true, "name": "get-buy-args-by-id", "description": "Get the args needed to buy a coin by its id" } } } }, "/v1/coins/buy/contract/{contractAddress}": { "get": { "description": "Retrieve the args needed to buy a coin using a wallet", "summary": "Get coin's buy args by contract address", "tags": [ "coins" ], "parameters": [ { "name": "contractAddress", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$" }, "description": "Contract address of the coin" }, { "name": "walletAddress", "in": "query", "description": "Address of the wallet that is going to buy the coin", "required": true, "schema": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$" } }, { "name": "amount", "in": "query", "description": "Amount of Base ETH in wei that is going to be swapped for the coin", "required": true, "schema": { "type": "string", "pattern": "[0-9]+" } } ], "responses": { "200": { "description": "Buy args retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "commands": { "type": "string", "pattern": "^0x[a-fA-F0-9]*", "description": "Commands needed to do a token swap" }, "inputs": { "type": "array", "items": { "type": "string", "pattern": "^0x[a-fA-F0-9]*" }, "description": "Inputs needed to do a token swap" } }, "required": [ "commands", "inputs" ] } } } }, "404": { "description": "Buy args not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getBuyArgsByContract", "x-mint": { "mcp": { "enabled": true, "name": "get-buy-args-by-contract", "description": "Get the args needed to buy a coin by its contract address" } } } }, "/v1/coins/sell/{id}": { "get": { "description": "Retrieve the args needed to sell a coin using a wallet that has it", "summary": "Get coin's sell args by ID", "tags": [ "coins" ], "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Id of the coin" }, { "name": "walletAddress", "in": "query", "description": "Address of the wallet that is going to sell the coin", "required": true, "schema": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$" } }, { "name": "amount", "in": "query", "description": "Amount of coin in wei that is going to be swapped to WETH", "required": true, "schema": { "type": "string", "pattern": "[0-9]+" } } ], "responses": { "200": { "description": "Sell args retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "commands": { "type": "string", "pattern": "^0x[a-fA-F0-9]*", "description": "Commands needed to do a token swap" }, "inputs": { "type": "array", "items": { "type": "string", "pattern": "^0x[a-fA-F0-9]*" }, "description": "Inputs needed to do a token swap" } }, "required": [ "commands", "inputs" ] } } } }, "404": { "description": "Sell args not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getSellArgsById", "x-mint": { "mcp": { "enabled": true, "name": "get-sell-args-by-id", "description": "Get the args needed to sell a coin by its id" } } } }, "/v1/coins/sell/contract/{contractAddress}": { "get": { "description": "Retrieve the args needed to sell a coin using a wallet that has it", "summary": "Get coin's sell args by contract address", "tags": [ "coins" ], "parameters": [ { "name": "contractAddress", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$" }, "description": "Contract address of the coin" }, { "name": "walletAddress", "in": "query", "description": "Address of the wallet that is going to sell the coin", "required": true, "schema": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$" } }, { "name": "amount", "in": "query", "description": "Amount of coin in wei that is going to be swapped to WETH", "required": true, "schema": { "type": "string", "pattern": "[0-9]+" } } ], "responses": { "200": { "description": "Sell args retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "commands": { "type": "string", "pattern": "^0x[a-fA-F0-9]*", "description": "Commands needed to do a token swap" }, "inputs": { "type": "array", "items": { "type": "string", "pattern": "^0x[a-fA-F0-9]*" }, "description": "Inputs needed to do a token swap" } }, "required": [ "commands", "inputs" ] } } } }, "404": { "description": "Sell args not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getSellArgsByContract", "x-mint": { "mcp": { "enabled": true, "name": "get-sell-args-by-contract", "description": "Get the args needed to sell a coin by its contract address" } } } }, "/v1/coins/quote/{id}": { "get": { "description": "Retrieve a quote for the amount of coin in exchange of ETH", "summary": "Get coin quote by ID", "tags": [ "coins" ], "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Paragraph-internal unique identifier for the coin" }, { "name": "amount", "in": "query", "description": "Amount of Base ETH in wei that is going to be swapped for the coin", "required": true, "schema": { "type": "string", "pattern": "[0-9]+" } } ], "responses": { "200": { "description": "Coin quote retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "quote": { "type": "string", "description": "Approximate number of coins that could be received in exchange of the amount of ETH entered" } }, "required": [ "quote" ] } } } }, "404": { "description": "Coin quote not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getQuoteById", "x-mint": { "mcp": { "enabled": true, "name": "get-quote-by-id", "description": "Get a quote of a coin by its ID" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Get coin quote by ID", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst quote = await api.coins.getQuote({ id: \"S2AlaNG5Hw0NdNptmLTw\", amount: \"1000000000000000000\" })" } ] } }, "/v1/coins/quote/contract/{contractAddress}": { "get": { "description": "Retrieve a quote for the amount of the coin in exchange of ETH", "summary": "Get coin quote by contract address", "tags": [ "coins" ], "parameters": [ { "name": "contractAddress", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Contract address of the coin" }, { "name": "amount", "in": "query", "description": "Amount of Base ETH in wei that is going to be swapped for the coin", "required": true, "schema": { "type": "string", "pattern": "[0-9]+" } } ], "responses": { "200": { "description": "Coin quote retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "quote": { "type": "string", "description": "Approximate number of coins that could be received in exchange of the amount of ETH entered" } }, "required": [ "quote" ] } } } }, "404": { "description": "Coin quote not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getQuoteByContract", "x-mint": { "mcp": { "enabled": true, "name": "get-quote-by-contract", "description": "Get a quote of a coin by its contract address" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Get coin quote by contract address", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst quote = await api.coins.getQuote({ contract: \"0xe9bb3166ff5f96381e257d509a801303b68e5d34\", amount: \"1000000000000000000\" })" } ] } }, "/v1/coins/list/popular": { "get": { "description": "Retrieve popular coins", "summary": "Get popular coins", "tags": [ "coins" ], "parameters": [], "responses": { "200": { "description": "Popular coins retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "coins": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Unique identifier for the coin" }, "contractAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Base contract address for the coin" }, "metadata": { "type": "object", "properties": { "name": { "type": "string", "description": "Name of the coin" }, "symbol": { "type": "string", "description": "Symbol of the coin" }, "decimals": { "type": "number", "description": "Number of decimals of the coin" }, "description": { "type": "string", "description": "Description of the coin" }, "image": { "type": "string", "description": "Image url of the logo associated with the coin" }, "logoURI": { "type": "string", "description": "Image url of the logo associated with the coin" }, "chainId": { "type": "number", "description": "Chain id number of the coin" }, "external_url": { "type": "string", "description": "External url associated with the coin" }, "links": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string", "description": "Name of the link" }, "url": { "type": "string", "description": "URL of the link" } }, "required": [ "name", "url" ] } }, "tags": { "type": "array", "items": { "type": "string" }, "description": "Tags associated with the coin" }, "extensions": { "type": "object", "properties": { "coinType": { "type": "string", "description": "Type of the coin" }, "paragraph": { "type": "object", "properties": { "blogId": { "type": "string", "description": "ID of the blog associated with this coin" }, "blogUrl": { "type": "string", "description": "URL of the blog associated with this coin" }, "authorName": { "type": "string", "description": "Name of the author associated with this coin" }, "noteId": { "type": "string", "description": "ID of the note associated with this coin" }, "postSlug": { "type": "string", "description": "Slug of the post associated with this coin" } }, "required": [ "blogId", "blogUrl" ] } }, "required": [ "coinType", "paragraph" ] }, "attributes": { "type": "array", "items": { "type": "object", "properties": { "trait_type": { "type": "string" }, "value": { "type": "string" } }, "required": [ "trait_type", "value" ] } } }, "required": [ "name", "symbol", "decimals", "description", "chainId", "external_url", "links", "tags", "extensions", "attributes" ] } }, "required": [ "id", "contractAddress", "metadata" ] } } }, "required": [ "coins" ] } } } }, "404": { "description": "Popular coins not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getPopularCoins", "x-mint": { "mcp": { "enabled": true, "name": "get-popular-coins", "description": "Get popular coins" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Get popular coins", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst { items: coins } = await api.coins.get({ sortBy: \"popular\" })" } ] } }, "/v1/subscribers/import": { "post": { "description": "Import subscribers from a CSV file into your publication. The publication is identified by the API key provided in the Authorization header.\n\n**File Requirements:**\n- Maximum file size: 10MB\n- Content type: text/csv\n\n**Supported CSV Columns:**\n- Email: `email` or `subscriberEmail` (case-insensitive)\n- Wallet: `wallet_address` (case-insensitive)\n- Created date: `created_at`, `subscription date`, `created`, or `createdAt` (case-insensitive, optional)\n\nAt least one of email or wallet_address must be present for each row. Rows with neither valid email nor valid wallet address will be skipped.", "summary": "Import subscribers from CSV", "tags": [ "subscribers" ], "parameters": [], "requestBody": { "description": "Body", "content": { "multipart/form-data": { "schema": { "type": "object", "properties": { "file": { "description": "CSV file containing subscriber data (max 10MB)" } } } } } }, "responses": { "200": { "description": "Import started successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ true ], "description": "Whether the import was started" } }, "required": [ "success" ] } } } }, "400": { "description": "Invalid request or CSV format", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "404": { "description": "Publication not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "importSubscribers", "x-mint": { "mcp": { "enabled": false, "name": "import-subscribers", "description": "Import subscribers from a CSV file into a publication" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Import subscribers from CSV", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nconst result = await api.subscribers.import(csvFile)" }, { "lang": "bash", "label": "Import subscribers using curl", "source": "curl -X POST \"https://public.api.paragraph.com/api/v1/subscribers/import\" \\\n -H \"Authorization: Bearer your-api-key\" \\\n -F \"file=@subscribers.csv;type=text/csv\"" } ], "security": [ { "apiKey": [] } ] } }, "/v1/subscribers": { "post": { "description": "Add a new subscriber to your publication. The publication is identified by the API key provided in the Authorization header.\n\n**Requirements:**\n- At least one of `email` or `wallet` must be provided\n- If both are provided, the subscriber will be associated with both credentials\n\n**Behavior:**\n- If the subscriber already exists (by email or wallet), they will not be duplicated", "summary": "Add a new subscriber", "tags": [ "subscribers" ], "parameters": [], "requestBody": { "description": "Body", "content": { "application/json": { "schema": { "type": "object", "properties": { "email": { "type": "string", "format": "email", "description": "Email address of the subscriber" }, "wallet": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Wallet address of the subscriber (0x format)" }, "createdAt": { "type": "number", "description": "Timestamp (in milliseconds) when the subscription was created. Defaults to current time." } } } } } }, "responses": { "200": { "description": "Subscriber added successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ true ], "description": "Whether the subscriber was added" } }, "required": [ "success" ] } } } }, "400": { "description": "Invalid request - must provide email or wallet", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "404": { "description": "Publication not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "addSubscriber", "x-mint": { "mcp": { "enabled": true, "name": "add-subscriber", "description": "Add a new subscriber to a publication" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Add subscriber with email", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nawait api.subscribers.create({ email: \"reader@example.com\" })" }, { "lang": "typescript", "label": "Add subscriber with wallet", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nawait api.subscribers.create({ wallet: \"0x1234...abcd\" })" }, { "lang": "bash", "label": "Add subscriber using curl", "source": "curl -X POST \"https://public.api.paragraph.com/api/v1/subscribers\" \\\n -H \"Authorization: Bearer your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"email\": \"reader@example.com\"}'" } ], "security": [ { "apiKey": [] } ] }, "delete": { "description": "Remove a subscriber from your publication. The publication is identified by the API key provided in the Authorization header. Identify the subscriber by email, wallet, or both.\n\n**Requirements:**\n- At least one of `email` or `wallet` must be provided\n- If both are provided, they must resolve to the same subscriber\n\n**Behavior:**\n- The subscription is hard-deleted, mirroring the dashboard's \"remove subscriber\" action", "summary": "Remove a subscriber", "tags": [ "subscribers" ], "parameters": [], "requestBody": { "description": "Body", "content": { "application/json": { "schema": { "type": "object", "properties": { "email": { "type": "string", "format": "email", "description": "Email address of the subscriber to remove" }, "wallet": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Wallet address of the subscriber to remove (0x format)" } } } } } }, "responses": { "200": { "description": "Subscriber removed successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ true ], "description": "Whether the subscriber was removed" } }, "required": [ "success" ] } } } }, "400": { "description": "Invalid request — must provide email or wallet, and both (if given) must resolve to the same subscriber", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "404": { "description": "Subscriber not found in this publication", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "removeSubscriber", "x-mint": { "mcp": { "enabled": true, "name": "remove-subscriber", "description": "Remove a subscriber from a publication" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Remove subscriber by email", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nawait api.subscribers.remove({ email: \"reader@example.com\" })" }, { "lang": "bash", "label": "Remove subscriber using curl", "source": "curl -X DELETE \"https://public.api.paragraph.com/api/v1/subscribers\" \\\n -H \"Authorization: Bearer your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"email\": \"reader@example.com\"}'" } ], "security": [ { "apiKey": [] } ] }, "get": { "description": "Retrieve a paginated list of subscribers for your publication. The publication is identified by the API key provided in the Authorization header.\n\n**Response:**\n- Returns subscriber email and/or wallet address\n- Only active subscribers are returned\n- Results are ordered by subscription date (newest first)", "summary": "List subscribers", "tags": [ "subscribers" ], "parameters": [ { "name": "cursor", "in": "query", "description": "Cursor for pagination", "schema": { "type": "string" } }, { "name": "limit", "in": "query", "description": "Maximum number of items to return (1-100, default: 10)", "schema": { "default": 10, "type": "integer", "minimum": 1, "maximum": 100 } } ], "responses": { "200": { "description": "Subscribers retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "items": { "type": "array", "items": { "type": "object", "properties": { "email": { "type": "string", "format": "email", "description": "Email address of the subscriber" }, "walletAddress": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$", "description": "Wallet address of the subscriber" }, "createdAt": { "type": "number", "description": "Timestamp when the subscription was created" } }, "required": [ "createdAt" ] }, "description": "Array of items in this page" }, "pagination": { "type": "object", "properties": { "cursor": { "type": "string", "description": "Cursor for fetching the next page of results" }, "hasMore": { "type": "boolean", "description": "Whether more results are available" }, "total": { "type": "number", "description": "Total number of items available" } }, "required": [ "hasMore" ] } }, "required": [ "items", "pagination" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "listSubscribers", "x-mint": { "mcp": { "enabled": true, "name": "list-subscribers", "description": "List subscribers for a publication" } }, "x-codeSamples": [ { "lang": "typescript", "label": "List subscribers with pagination", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nconst { items: subscribers, pagination } = await api.subscribers.get({ limit: 50 })" }, { "lang": "bash", "label": "List subscribers using curl", "source": "curl -X GET \"https://public.api.paragraph.com/api/v1/subscribers?limit=50\" \\\n -H \"Authorization: Bearer your-api-key\"" } ], "security": [ { "apiKey": [] } ] } }, "/v1/discover/search": { "get": { "description": "Search for posts across all publications. Returns results ranked by relevance, popularity, and recency.", "summary": "Search posts", "tags": [ "discover" ], "parameters": [ { "name": "q", "in": "query", "description": "Search query string", "schema": { "type": "string" } }, { "name": "blogId", "in": "query", "description": "Optional publication ID to restrict search to a specific publication", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Post search results", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "properties": { "post": { "type": "object", "properties": { "postId": { "type": "string", "description": "Unique identifier for the post" }, "blogId": { "type": "string", "description": "ID of the publication this post belongs to" }, "createdAt": { "type": "string", "description": "Timestamp when the post was created" }, "publishedAt": { "type": [ "string", "null" ], "description": "Timestamp when the post was published" }, "title": { "type": [ "string", "null" ], "description": "Title of the post" }, "subtitle": { "type": [ "string", "null" ], "description": "Subtitle of the post" }, "postPreview": { "type": [ "string", "null" ], "description": "Preview text of the post" }, "coverImageUrl": { "type": [ "string", "null" ], "description": "URL to the post's cover image" }, "slug": { "type": [ "string", "null" ], "description": "URL-friendly identifier for the post" }, "coinId": { "type": [ "string", "null" ], "description": "Associated coin ID, if any" } }, "required": [ "postId", "blogId", "createdAt", "publishedAt", "title", "subtitle", "postPreview", "coverImageUrl", "slug", "coinId" ], "description": "The matched post" }, "blog": { "type": "object", "properties": { "blogId": { "type": "string", "description": "Unique identifier for the publication" }, "userId": { "type": "string", "description": "ID of the publication owner" }, "name": { "type": [ "string", "null" ], "description": "Display name of the publication" }, "url": { "type": [ "string", "null" ], "description": "URL of the publication" }, "slug": { "type": [ "string", "null" ], "description": "URL-friendly slug of the publication" }, "logoUrl": { "type": [ "string", "null" ], "description": "URL to the publication's logo" }, "coinId": { "type": [ "string", "null" ], "description": "Associated coin ID, if any" }, "customDomain": { "type": [ "string", "null" ], "description": "Custom domain for the publication" }, "summary": { "type": [ "string", "null" ], "description": "Brief description of the publication" } }, "required": [ "blogId", "userId", "name", "url", "slug", "logoUrl", "coinId" ], "description": "The publication this post belongs to" }, "user": { "type": "object", "properties": { "userId": { "type": "string", "description": "Unique identifier for the user" }, "name": { "type": [ "string", "null" ], "description": "Display name of the author" }, "bio": { "type": [ "string", "null" ], "description": "Brief biography of the author" }, "avatarUrl": { "type": [ "string", "null" ], "description": "URL to the author's avatar" }, "walletAddress": { "type": [ "string", "null" ], "description": "Wallet address of the author" } }, "required": [ "userId", "name" ], "description": "The author of the post" } }, "required": [ "post", "blog", "user" ] } } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "searchPosts", "x-mint": { "mcp": { "enabled": true, "name": "search-posts", "description": "Search for posts across all publications by keyword" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Search posts", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst results = await api.discover.searchPosts({ q: \"web3 publishing\" })" }, { "lang": "bash", "label": "Search posts using curl", "source": "curl \"https://public.api.paragraph.com/api/v1/discover/search?q=web3+publishing\"" } ] } }, "/v1/discover/blogs/search": { "get": { "description": "Search for publications by name, slug, or description. Returns results ranked by relevance and subscriber count.", "summary": "Search publications", "tags": [ "discover" ], "parameters": [ { "name": "q", "in": "query", "description": "Search query string", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Publication search results", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "properties": { "blog": { "type": "object", "properties": { "blogId": { "type": "string", "description": "Unique identifier for the publication" }, "userId": { "type": "string", "description": "ID of the publication owner" }, "name": { "type": [ "string", "null" ], "description": "Display name of the publication" }, "url": { "type": [ "string", "null" ], "description": "URL of the publication" }, "slug": { "type": [ "string", "null" ], "description": "URL-friendly slug of the publication" }, "logoUrl": { "type": [ "string", "null" ], "description": "URL to the publication's logo" }, "coinId": { "type": [ "string", "null" ], "description": "Associated coin ID, if any" }, "customDomain": { "type": [ "string", "null" ], "description": "Custom domain for the publication" }, "summary": { "type": [ "string", "null" ], "description": "Brief description of the publication" } }, "required": [ "blogId", "userId", "name", "url", "slug", "logoUrl", "coinId" ], "description": "The matched publication" }, "user": { "type": "object", "properties": { "userId": { "type": "string", "description": "Unique identifier for the user" }, "name": { "type": [ "string", "null" ], "description": "Display name of the author" }, "bio": { "type": [ "string", "null" ], "description": "Brief biography of the author" }, "avatarUrl": { "type": [ "string", "null" ], "description": "URL to the author's avatar" }, "walletAddress": { "type": [ "string", "null" ], "description": "Wallet address of the author" } }, "required": [ "userId", "name" ], "description": "The publication owner" }, "activeSubscriberCount": { "type": "number", "description": "Number of active subscribers to this publication" } }, "required": [ "blog", "user", "activeSubscriberCount" ] } } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "searchBlogs", "x-mint": { "mcp": { "enabled": true, "name": "search-publications", "description": "Search for publications by name or description" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Search publications", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst results = await api.discover.searchBlogs({ q: \"crypto\" })" }, { "lang": "bash", "label": "Search publications using curl", "source": "curl \"https://public.api.paragraph.com/api/v1/discover/blogs/search?q=crypto\"" } ] } }, "/v1/discover/coins/search": { "get": { "description": "Search for writer coins by ticker, contract address, or publication name. Returns results ranked by relevance and subscriber count.", "summary": "Search coins", "tags": [ "discover" ], "parameters": [ { "name": "q", "in": "query", "description": "Search query string", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Coin search results", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "properties": { "coin": { "type": "object", "properties": { "coinId": { "type": "string", "description": "Unique identifier for the coin" }, "ticker": { "type": [ "string", "null" ], "description": "Ticker symbol of the coin" }, "contractAddress": { "type": [ "string", "null" ], "description": "Contract address of the coin" }, "blogId": { "type": "string", "description": "ID of the associated publication" } }, "required": [ "coinId", "ticker", "contractAddress", "blogId" ], "description": "The matched coin" }, "blog": { "type": "object", "properties": { "blogId": { "type": "string", "description": "Unique identifier for the publication" }, "name": { "type": [ "string", "null" ], "description": "Display name of the publication" }, "slug": { "type": [ "string", "null" ], "description": "URL-friendly slug of the publication" }, "logoUrl": { "type": [ "string", "null" ], "description": "URL to the publication's logo" } }, "required": [ "blogId", "name", "slug", "logoUrl" ], "description": "The associated publication" }, "activeSubscriberCount": { "type": "number", "description": "Number of active subscribers to this publication" } }, "required": [ "coin", "blog", "activeSubscriberCount" ] } } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "searchCoins", "x-mint": { "mcp": { "enabled": true, "name": "search-coins", "description": "Search for writer coins by ticker, contract address, or publication name" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Search coins", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI()\nconst results = await api.discover.searchCoins({ q: \"$WRITER\" })" }, { "lang": "bash", "label": "Search coins using curl", "source": "curl \"https://public.api.paragraph.com/api/v1/discover/coins/search?q=WRITER\"" } ] } }, "/v1/analytics/query": { "post": { "description": "Execute a read-only SQL query against the analytics schema, scoped to your publication.\n\n**Auth:** Requires an API key. Queries run as the publication that owns the API key; Row-Level Security guarantees that only that publication's rows are visible even if the SQL is unscoped.\n\n**SQL requirements:**\n- `SELECT` or `WITH` (CTE) statements only\n- Reference tables unprefixed (e.g. `FROM posts`) — the `analytics` schema is the default `search_path`\n- No semicolons, no writes, no DDL, no superuser functions\n- Hard limit of 10,000 rows; anything over is truncated and `truncated: true` is returned\n- 30-second statement timeout\n\n**Discovering the schema:** call `GET /v1/analytics/schema` for column metadata.\n\nCommon queries: open rate, subscriber count, top posts by views, engagement over time, click-through rate.\n\nFor raw post-scoped tables, join through `posts.draft_of` to roll draft/version rows up to the canonical published post.", "summary": "Run an analytics SQL query", "tags": [ "analytics" ], "parameters": [], "requestBody": { "description": "Body", "content": { "application/json": { "schema": { "type": "object", "properties": { "sql": { "type": "string", "minLength": 1, "description": "A SELECT or WITH query against the analytics schema. The analytics.* prefix is implicit." } }, "required": [ "sql" ] } } } }, "responses": { "200": { "description": "Query executed successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "rows": { "type": "array", "items": { "type": "object", "additionalProperties": {} }, "description": "Result rows. Each row is a column-name → value map." }, "rowCount": { "type": "integer", "description": "Number of rows returned (after truncation if any)" }, "fields": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" } }, "required": [ "name" ] }, "description": "Column names in row order" }, "truncated": { "type": "boolean", "description": "True if the result was truncated at the 10,000 row limit" } }, "required": [ "rows", "rowCount", "fields", "truncated" ] } } } }, "400": { "description": "Invalid SQL — check the validator message", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "404": { "description": "Publication not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "408": { "description": "Query timed out (30s). Try a more targeted query or a materialized view.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "analyticsQuery", "x-mint": { "mcp": { "enabled": true, "name": "analytics-query", "description": "Run a SELECT query against your publication's analytics data (views, subscribers, open rate, etc.)" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Top posts by views in the last 30 days", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nconst { rows } = await api.analytics.query({\n sql: `SELECT title, total_views\n FROM post_analytics_summary\n WHERE published_at > now() - interval '30 days'\n ORDER BY total_views DESC\n LIMIT 10`,\n})" }, { "lang": "bash", "label": "Query via curl", "source": "curl -X POST \"https://public.api.paragraph.com/api/v1/analytics/query\" \\\n -H \"Authorization: Bearer your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"sql\": \"SELECT COUNT(*) FROM subscribers\"}'" } ], "security": [ { "apiKey": [] } ] } }, "/v1/analytics/schema": { "get": { "description": "Returns column metadata for every table and view in the analytics schema. Use this to discover available tables/columns before writing an analytics query.", "summary": "Describe the analytics schema", "tags": [ "analytics" ], "parameters": [], "responses": { "200": { "description": "Schema metadata retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "tables": { "type": "array", "items": { "type": "object", "properties": { "table_name": { "type": "string" }, "column_name": { "type": "string" }, "data_type": { "type": "string" }, "is_nullable": { "type": "string" } }, "required": [ "table_name", "column_name", "data_type", "is_nullable" ] }, "description": "One row per column, grouped by table in ordinal order" } }, "required": [ "tables" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "analyticsSchema", "x-mint": { "mcp": { "enabled": true, "name": "analytics-schema", "description": "List tables and columns available in your publication's analytics schema" } }, "x-codeSamples": [ { "lang": "typescript", "label": "List analytics tables", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nconst { tables } = await api.analytics.schema()" }, { "lang": "bash", "label": "Fetch schema via curl", "source": "curl -H \"Authorization: Bearer your-api-key\" \\\n \"https://public.api.paragraph.com/api/v1/analytics/schema\"" } ], "security": [ { "apiKey": [] } ] } }, "/v1/emails/send": { "post": { "description": "Send an email from your publication to a list of recipient addresses.\n\n**Eligibility:**\n- Publications must be approved by Paragraph before they can send custom emails. Ineligible publications receive a 403. Eligibility is managed by Paragraph and is not user-configurable.\n\n**Per-recipient filtering:**\n- Malformed addresses and known disposable domains are skipped.\n- Addresses that previously unsubscribed from this publication are skipped as `suppressed`.\n- Skipped recipients are returned in the response; nothing else is delivered to them.\n\n**Delivery:**\n- `body` is treated as Markdown and rendered to HTML server-side.\n- Each recipient receives the email individually (not as a BCC blast) with a mandatory unsubscribe footer.\n- Sends are queued asynchronously; a 200 response means recipients were accepted, not delivered.\n\n**Caps:**\n- Maximum of 10,000 addresses per call (request-level sanity check).", "summary": "Send a custom email", "tags": [ "emails" ], "parameters": [], "requestBody": { "description": "Body", "content": { "application/json": { "schema": { "type": "object", "properties": { "subject": { "type": "string", "minLength": 1, "maxLength": 998, "description": "Subject line of the email" }, "body": { "type": "string", "minLength": 1, "maxLength": 100000, "description": "Email body. Markdown; rendered to HTML server-side. Max 100KB." }, "emails": { "type": "array", "items": { "type": "string", "minLength": 3, "maxLength": 254 }, "minItems": 1, "maxItems": 10000, "description": "Recipient email addresses (max 10,000). Malformed addresses are returned in `skipped` with `reason: \"invalid\"` rather than rejecting the whole request." }, "dryRun": { "type": "boolean", "description": "If true, run filtering and return the accepted/skipped split without scheduling delivery" } }, "required": [ "subject", "body", "emails" ] } } } }, "responses": { "200": { "description": "Send request accepted", "content": { "application/json": { "schema": { "type": "object", "properties": { "accepted": { "type": "integer", "description": "Number of recipients queued for delivery (or that would be queued when dryRun is true)" }, "skipped": { "type": "array", "items": { "type": "object", "properties": { "email": { "type": "string" }, "reason": { "type": "string", "enum": [ "suppressed", "invalid", "scheduling_failed" ] } }, "required": [ "email", "reason" ] }, "description": "Recipients that were rejected, with the reason each one was skipped. `scheduling_failed` means filtering passed but the delivery task could not be queued — retry these addresses." } }, "required": [ "accepted", "skipped" ] } } } }, "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "401": { "description": "Invalid or missing API key", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "403": { "description": "Publication is not eligible to send custom emails", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "404": { "description": "Publication not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } }, "503": { "description": "Publication temporarily can't send through this endpoint. Contact support.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "sendCustomEmail", "x-mint": { "mcp": { "enabled": true, "name": "send-custom-email", "description": "Send a markdown email from your publication to a list of recipient addresses" } }, "x-codeSamples": [ { "lang": "typescript", "label": "Send an email to a list of recipients", "source": "import { ParagraphAPI } from \"@paragraph-com/sdk\"\n\nconst api = new ParagraphAPI({ apiKey: \"your-api-key\" })\nconst result = await api.emails.send({\n subject: \"Hello from Paragraph\",\n body: \"# Welcome\\n\\nThanks for reading.\",\n emails: [\"reader@example.com\"],\n})" }, { "lang": "bash", "label": "Send an email using curl", "source": "curl -X POST \"https://public.api.paragraph.com/api/v1/emails/send\" \\\n -H \"Authorization: Bearer your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"subject\":\"Hello\",\"body\":\"# Hi\",\"emails\":[\"reader@example.com\"]}'" } ], "security": [ { "apiKey": [] } ] } }, "/v1/api/auth/sessions": { "post": { "description": "Creates a new browser-based auth session for CLI or other API clients. The returned verification URL should be opened in the user's browser to complete authentication.", "summary": "Create an API auth session", "tags": [ "auth" ], "parameters": [], "requestBody": { "description": "Body", "content": { "application/json": { "schema": { "type": "object", "properties": { "deviceName": { "type": "string", "maxLength": 100, "description": "Name of the device requesting access (e.g. user@MacBook-Pro.local)" }, "callbackUrl": { "type": "string", "format": "uri", "maxLength": 2048, "description": "HTTPS callback URL to redirect the user to after approving the session" } } } } } }, "responses": { "201": { "description": "Session created successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "sessionId": { "type": "string", "description": "Unique session identifier" }, "verificationUrl": { "type": "string", "description": "URL to open in the browser to approve the session" }, "expiresAt": { "type": "string", "description": "ISO 8601 timestamp when the session expires" } }, "required": [ "sessionId", "verificationUrl", "expiresAt" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "createAuthSession" } }, "/v1/api/auth/sessions/{sessionId}": { "get": { "description": "Poll the status of an auth session. Returns the API key once the session has been approved in the browser.", "summary": "Poll an API auth session", "tags": [ "auth" ], "parameters": [ { "name": "sessionId", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Session ID returned from create" } ], "responses": { "200": { "description": "Current session status", "content": { "application/json": { "schema": { "oneOf": [ { "type": "object", "properties": { "status": { "type": "string", "enum": [ "pending" ] }, "deviceName": { "type": "string" }, "callbackUrl": { "type": "string" } }, "required": [ "status", "deviceName" ] }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "completed" ] }, "apiKey": { "type": "string" } }, "required": [ "status", "apiKey" ] }, { "type": "object", "properties": { "status": { "type": "string", "enum": [ "expired" ] } }, "required": [ "status" ] } ] } } } }, "404": { "description": "Session not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string" } }, "required": [ "message" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "getAuthSession" }, "delete": { "description": "Cancels a pending auth session. Only pending sessions can be denied.", "summary": "Deny an API auth session", "tags": [ "auth" ], "parameters": [ { "name": "sessionId", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Session ID to deny" } ], "responses": { "200": { "description": "Session denied successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ true ] } }, "required": [ "success" ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "enum": [ false ], "description": "Always false for error responses" }, "msg": { "type": "string", "description": "Human-readable error message" } }, "required": [ "success", "msg" ] } } } } }, "operationId": "deleteAuthSession" } } }, "info": { "title": "Paragraph API", "version": "1.0.0", "description": "Public API for interacting with Paragraph publications, posts, users, and coined writing.\n\n## Rate Limiting\nAPI requests are rate-limited to ensure fair usage. Contact support@paragraph.com for higher limits.\n\n## Pagination\nList endpoints support cursor-based pagination using `cursor` and `limit` parameters.", "contact": { "name": "Paragraph Support", "email": "support@paragraph.com", "url": "https://paragraph.com/support" }, "license": { "name": "MIT", "url": "https://opensource.org/licenses/MIT" } }, "servers": [ { "url": "https://public.api.paragraph.com/api", "description": "Production server" } ], "tags": [ { "name": "publications", "description": "Operations related to publications" }, { "name": "posts", "description": "Operations related to posts and content" }, { "name": "users", "description": "Operations related to users and authors" }, { "name": "coins", "description": "Operations related to tokenized content" }, { "name": "subscribers", "description": "Operations related to subscriber management (requires API key)" } ], "security": [ {} ], "components": { "securitySchemes": { "apiKey": { "type": "http", "scheme": "bearer", "description": "API key for authenticating protected endpoints. Pass as Bearer token in Authorization header." } } }, "x-mint": { "mcp": { "enabled": true } } }