### Install Metricool MCP via Cursor deep link
Source: https://help.metricool.com/how-to-connect-metricools-mcp-eqp9h
Use this deep link to install the Metricool MCP server in Cursor Desktop. Opening it in a browser prompts Cursor to add the MCP server, then you connect and authorize.
```text
cursor://anysphere.cursor-deeplink/mcp/install?name=metricool-mcp&config=eyJ1cmwiOiJodHRwczovL2FpLm1ldHJpY29vbC5jb20vbWNwIiwidHlwZSI6Imh0dHAifQ%3D%3D
```
--------------------------------
### iframe integration example
Source: https://help.metricool.com/wli-integration-methods-tryyk
A basic implementation of the Metricool iframe. The src attribute is specific to the brand and access level, and the example includes a redirect parameter.
```javascript
```
--------------------------------
### GET /v2/scheduler/posts/approvals-config
Source: https://help.metricool.com/basic-guide-for-api-integration-r97af
Gets the brand configuration for sending a post to review.
```APIDOC
## GET /v2/scheduler/posts/approvals-config
### Description
Gets the brand configuration for sending a post to review.
### Method
GET
### Endpoint
https://app.metricool.com/api/v2/scheduler/posts/approvals-config
### Parameters
No parameters documented in the source.
### Request Example
No request example provided in the source.
### Response
#### Success Response (200)
No response schema provided in the source.
#### Response Example
No response example provided in the source.
```
--------------------------------
### Retrieve blogId from URL
Source: https://help.metricool.com/common-questions-and-errors-when-using-the-api-8x9nq
Example URL structure showing where to locate the blogId and userId parameters.
```plaintext
https://app.metricool.com/evolution/web?blogId=00000&userId=0000000
```
--------------------------------
### GET /api/admin/add-profile
Source: https://help.metricool.com/wli-brand-creation-endpoint-example-on-a-custom-backend-proxy-eql6w
Creates a new brand/profile in Metricool. Requires authentication via the X-Mc-Auth header and a userId query parameter. This is a GET request with a side effect and is not idempotent.
```APIDOC
## GET /api/admin/add-profile
### Description
Creates a new brand/profile in Metricool. This endpoint is part of the Admin Service and is used to add a new profile. It requires authentication and a userId query parameter.
### Method
GET
### Endpoint
https://app.metricool.com/api/admin/add-profile?userId={userId}
### Parameters
#### Query Parameters
- **userId** (string) - Required - The Metricool user ID for which the profile is created.
### Headers
- **X-Mc-Auth** (string) - Required - Your user token for authentication.
### Request Example
No request body is required. The request is a GET call with the userId query parameter.
### Response
#### Success Response (200)
Returns a PublicBlog JS object describing the new brand.
#### Response Example
No explicit response example is provided in the source.
### Error Handling
Error responses are not guaranteed to be valid JSON; they should be read as text first.
```
--------------------------------
### Wrap Server Socket with SSL Context
Source: https://help.metricool.com/wli-setting-up-the-sample-backend-proxy-nc0fs
Configure the SSL context and wrap the server socket before starting the server to enable HTTPS.
```python
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certfile=CERTFILE, keyfile=KEYFILE)
httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
```
--------------------------------
### Set up Gemini CLI with Metricool MCP
Source: https://help.metricool.com/how-to-connect-metricools-mcp-eqp9h
Steps to set up Gemini CLI with Metricool MCP: install the CLI, edit the system defaults file to add the MCP server, and authenticate with the /mcp auth metricool command.
```bash
npm install -g @google/gemini-cli
```
```json
{
"mcpServers": {
"metricool": {
"httpUrl": "https://ai.metricool.com/mcp"
}
},
"security": {
"auth": {
"selectedType": "oauth-personal"
}
}
}
```
```bash
/mcp auth metricool
```
--------------------------------
### API request for autoin link creation
Source: https://help.metricool.com/wli-common-errors-during-iframe-integration-8b1uz
An example of an API request used to automate the creation of the autoin link.
```text
https://app.metricool.com/api/admin/profile?blogId=&userId=&refreshBrandCache=false
```
--------------------------------
### Example body for scheduling a post
Source: https://help.metricool.com/wli-scheduling-endpoints-example-on-a-custom-backend-proxy-frko7
JSON body for the scheduler endpoint. Includes publicationDate with timezone, text, providers, autoPublish, draft, shortener, saveExternalMediaFiles, and creatorUserMail. Note: if media is included, set saveExternalMediaFiles to true.
```json
{
"publicationDate": {
"dateTime": "2026-08-01T10:00:00",
"timezone": "Europe/Madrid"
},
"text": "Yeah, team! This is a scheduled post test for White Label Integration.",
"providers": [
{ "network": "facebook" }
],
"autoPublish": true,
"draft": false,
"shortener": false,
"saveExternalMediaFiles": false,
"creatorUserMail": "me@example.com"
}
```
--------------------------------
### White Label Autoin Token URL vs Metricool API Token
Source: https://help.metricool.com/wli-common-errors-during-iframe-api-integration-8b1uz
The first URL is the general structure of an autoin link for iframe creation, using the White Label Token. The second is an example of a Get request to the Metricool API to automate the creation of the autoin link. The White Label Token is unique per brand and can be found in Menu > Brand Settings > White Label.
```javascript
https://app.metricool.com/autoin/[WL_TOKEN]?redirect=/planner
```
```javascript
https://app.metricool.com/api/admin/profile?blogId=&userId=&refreshBrandCache=false
```
--------------------------------
### Normalize media URL
Source: https://help.metricool.com/basic-guide-for-api-integration-r97af
Perform a GET request to host the media on Metricool servers. The URL must be public and non-expiring.
```plaintext
https://app.metricool.com/api/actions/normalize/image/url?url=
```
--------------------------------
### Add Metricool MCP server to Claude Code
Source: https://help.metricool.com/how-to-connect-metricools-mcp-with-claude-0l84v
Run this command in the terminal where you use Claude Code to add the Metricool MCP server over HTTP. Requires Claude Code Pro or Max subscription and prior installation of Claude Code.
```bash
claude mcp add --transport http metricool https://ai.metricool.com/mcp
```
--------------------------------
### GET /v2/scheduler/posts/{id}
Source: https://help.metricool.com/basic-guide-for-api-integration-r97af
Gets a scheduled post by its ID.
```APIDOC
## GET /v2/scheduler/posts/{id}
### Description
Gets a scheduled post by its ID.
### Method
GET
### Endpoint
https://app.metricool.com/api/v2/scheduler/posts/{id}
### Parameters
#### Path Parameters
- **id** (string) - Required - The ID of the scheduled post.
### Request Example
No request example provided in the source.
### Response
#### Success Response (200)
No response schema provided in the source.
#### Response Example
No response example provided in the source.
```
--------------------------------
### Create an empty slot in the autolist (GET request)
Source: https://help.metricool.com/add-content-to-an-autolist-using-the-api-q3wl0
Use this GET request to reserve a position in the autolist. The response includes the new item's id, which you'll use as postid in the next step. Note: every call adds a new empty row, even if you don't complete the next step.
```http
GET https://app.metricool.com/api/lists/posts/create?listid={listId}&position={position}&userId={userId}&blogId={blogId}
```
--------------------------------
### GET /v2/scheduler/posts/instagram-properties
Source: https://help.metricool.com/basic-guide-for-api-integration-r97af
Gets the Instagram post properties of a brand.
```APIDOC
## GET /v2/scheduler/posts/instagram-properties
### Description
Gets the Instagram post properties of a brand.
### Method
GET
### Endpoint
https://app.metricool.com/api/v2/scheduler/posts/instagram-properties
### Parameters
No parameters documented in the source.
### Request Example
No request example provided in the source.
### Response
#### Success Response (200)
No response schema provided in the source.
#### Response Example
No response example provided in the source.
```
--------------------------------
### GET /admin/add-profile
Source: https://help.metricool.com/wli-common-errors-during-iframe-integration-8b1uz
Endpoint for creating a new brand/profile. Requires authentication headers and may return errors if the maximum number of brands is reached or if a collaborator attempts to create a brand.
```APIDOC
## GET /admin/add-profile
### Description
Creates a new brand/profile. Requires authentication headers and may return errors if the maximum number of brands is reached or if a collaborator attempts to create a brand.
### Method
GET
### Endpoint
/admin/add-profile
### Parameters
#### Headers
- **X-Mc-Auth** (string) - Required - Access token (userToken)
- **Content-Type** (string) - Required - application/json
- **userId** (string) - Required - User ID
### Response
#### Success Response (200)
- **body** (string) - Returns 'ok - {empty}' when successful, but may indicate an error if no more room for brands or if a collaborator tries to create one.
#### Error Responses
- **401 Unauthorized** - Missing access key. Add the access token (userToken) and the userId into the request call.
- **ok - {empty}** - There's no more room for another brand, or a collab is trying to create a new one. Check the maximum number of brands isn't reached yet. Remember only the master account can create new brands by using the API.
```
--------------------------------
### GET /v2/scheduler/posts
Source: https://help.metricool.com/basic-guide-for-api-integration-r97af
Lists scheduled posts between two dates.
```APIDOC
## GET /v2/scheduler/posts
### Description
Lists scheduled posts between two dates.
### Method
GET
### Endpoint
https://app.metricool.com/api/v2/scheduler/posts
### Parameters
No parameters documented in the source.
### Request Example
No request example provided in the source.
### Response
#### Success Response (200)
No response schema provided in the source.
#### Response Example
No response example provided in the source.
```
--------------------------------
### GET /v2/settings/brands/connections/anonymous-link
Source: https://help.metricool.com/wli-brand-connections-panel-for-end-clients-through-api-4m5b3
Retrieves the currently valid anonymous link for the brand. Returns 404 if no link exists yet.
```APIDOC
## [GET] /v2/settings/brands/connections/anonymous-link
### Description
Retrieves the currently valid anonymous link for the brand. Returns 404 if no link exists yet.
### Method
GET
### Endpoint
https://app.metricool.com/api/v2/settings/brands/connections/anonymous-link?blogId={blogId}&userId={userId}
### Parameters
#### Query Parameters
- **blogId** (string) - Required - The ID of the brand.
- **userId** (string) - Required - The ID of the user.
### Request Example
No request body is required.
### Response
#### Success Response (200)
- **data.link** (string) - The shareable link.
- **data.expiresAt** (object) - Expiration date and timezone.
#### Response Example
{
"data": {
"link": "https://mtr.cool/AB3XY9Z",
"expiresAt": {
"dateTime": "2026-09-03T13:36:39",
"timezone": "Europe/Madrid"
}
}
}
#### Error Responses
- **404** - The brand has no valid link yet.
- **403** - The user can't edit the brand, or the plan is below Advanced.
```
--------------------------------
### Metricool Add Profile Endpoint Definition
Source: https://help.metricool.com/wli-brand-creation-endpoint-example-on-a-custom-backend-proxy-eql6w
The GET request structure for the add-profile endpoint, requiring the X-Mc-Auth header.
```javascript
GET https://app.metricool.com/api/admin/add-profile?userId={userId}
```
--------------------------------
### Client-side fetch request to Metricool API
Source: https://help.metricool.com/wli-integration-architecture-customer-success-approach-xjxku
Example of a direct browser-side call that fails due to CORS preflight restrictions and token exposure risks.
```javascript
// Called from client-side (domain) JS — fails before it reaches Metricool's domain
fetch('https://app.metricool.com/api/v2/scheduler/posts', {
method: 'POST',
headers: {
'X-Mc-Auth': '[YOUR_TOKEN]',
'Content-Type': 'application/json'
},
body: JSON.stringify({ /* ... */ })
});
// → browser sends a preflight OPTIONS request → Metricool responds 403 Forbidden
```
--------------------------------
### Add Metricool MCP to Cursor mcp.json
Source: https://help.metricool.com/how-to-connect-metricools-mcp-eqp9h
These JSON blocks show how to manually add the Metricool MCP server to Cursor's mcp.json file. Start with the default empty mcpServers object, add the metricool-mcp entry inside it, and keep the full file as shown. Save the file to use the server.
```json
{
"mcpServers": {}
}
```
```json
"metricool-mcp": {
"url": "https://ai.metricool.com/mcp",
"type": "http"
}
```
```json
{
"mcpServers": {
"metricool-mcp": {
"url": "https://ai.metricool.com/mcp",
"type": "http"
}
}
}
```
--------------------------------
### 404 not found response body
Source: https://help.metricool.com/wli-brand-connections-panel-for-end-clients-through-api-4m5b3
The standard not-found body returned when calling GET before any link exists for the brand.
```json
{
"status": "NOT_FOUND",
"code": "404",
"detail": "404 NOT_FOUND"
}
```
--------------------------------
### GET /api/lists/posts/create
Source: https://help.metricool.com/add-content-to-an-autolist-using-the-api-q3wl0
Creates an empty slot in an autolist, reserving a position. The response includes the full autolist array with the new item's id, which is used as postid in the next step.
```APIDOC
## GET /api/lists/posts/create
### Description
Creates an empty slot in an autolist, reserving a position. The response includes the full autolist array with the new item's id, which is used as postid in the next step.
### Method
GET
### Endpoint
https://app.metricool.com/api/lists/posts/create?listid={listId}&position={position}&userId={userId}&blogId={blogId}
### Parameters
#### Query Parameters
- **listid** (string) - Required - The autolist's internal ID.
- **position** (integer) - Required - Where to insert the new post. 0 inserts it at the top of the list.
- **userId** (string) - Required - Your Metricool user identifier.
- **blogId** (string) - Required - The brand/profile identifier.
### Response
#### Success Response (200)
- **id** (string) - The new item's id, used as postid in the next step.
- **full autolist array** (array) - The complete autolist including the new item.
### Notes
- Every call to this endpoint adds a new empty row to the autolist, even if the next step is not completed. Repeated calls build up empty rows.
- This endpoint only accepts GET; using POST results in a 500 InternalError.
```
--------------------------------
### Anonymous link response body
Source: https://help.metricool.com/wli-brand-connections-panel-for-end-clients-through-api-4m5b3
The JSON body returned by both GET and POST when a link exists. Contains the link URL and its expiration date with timezone.
```json
{
"data": {
"link": "https://mtr.cool/AB3XY9Z",
"expiresAt": {
"dateTime": "2026-09-03T13:36:39",
"timezone": "Europe/Madrid"
}
}
}
```
--------------------------------
### Add Referrer Policy to iframe for CSP frame-ancestors error
Source: https://help.metricool.com/wli-common-errors-during-iframe-api-integration-8b1uz
Add the Referrer Policy attribute to your iframe, before the source (src), to fix Content-Security-Policy frame-ancestors errors. The example shows the attribute set to 'origin'.
```javascript
```
--------------------------------
### GET anonymous link request
Source: https://help.metricool.com/wli-brand-connections-panel-for-end-clients-through-api-4m5b3
Retrieves the currently valid anonymous link for a brand. Returns 200 with the link and expiration date, 404 if no link exists, or 403 if the user can't edit the brand or the plan is below Advanced.
```plaintext
GET https://app.metricool.com/api/v2/settings/brands/connections/anonymous-link?blogId={blogId}&userId={userId}
```
--------------------------------
### Define SSL Certificate and Key Files
Source: https://help.metricool.com/wli-setting-up-the-sample-backend-proxy-nc0fs
Specify the paths to your domain's certificate and private key files for the proxy.
```python
KEYFILE = "iframe_key.pem"
CERTFILE = "iframe_cert.pem"
```
--------------------------------
### Fill the slot with content (POST request)
Source: https://help.metricool.com/add-content-to-an-autolist-using-the-api-q3wl0
Send this POST request as form-data, not JSON. Include the listid, text, postid (from the previous step), and pictures. When there's no image, send [] to avoid silent failure.
```http
POST https://app.metricool.com/api/lists/posts/updatepostlist?userId={userId}&blogId={blogId}
```
--------------------------------
### Claude Desktop config for Metricool MCP with API key
Source: https://help.metricool.com/how-to-connect-metricools-mcp-with-claude-0l84v
Alternative JSON configuration for the Claude Desktop config file that authenticates with an API key instead of browser OAuth. Replace with your actual key. This configuration skips the browser authorization step.
```json
{
"mcpServers": {
"metricool-mcp": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://ai.metricool.com/mcp",
"--header",
"X-Mc-Auth: "
]
}
}
}
```
--------------------------------
### Backend: Map local route to Metricool route
Source: https://help.metricool.com/wli-integration-architecture-customer-success-approach-xjxku
Server-side logic that maps the local path /api/scheduler/posts to the real Metricool route /v2/scheduler/posts, and handles other /api/ paths by stripping the /api prefix. This runs after the proxy receives the request and before forwarding it with the token.
```python
# server-side — local route → real Metricool route
if path == "/api/scheduler/posts":
remote_path = "/v2/scheduler/posts"
elif path.startswith("/api/"):
remote_path = path[len("/api"):]
```
--------------------------------
### Backend: Attach X-Mc-Auth header with token from environment
Source: https://help.metricool.com/wli-integration-architecture-customer-success-approach-xjxku
Used on the backend only to read the Metricool user token from an environment variable and attach it as the X-Mc-Auth header on requests forwarded to Metricool. Never include this in files served to the browser. If the token is ever exposed, treat it as compromised and regenerate it from Metricool → Account Settings → API.
```python
# On the backend only — never in a file served to the browser
METRICOOL_USER_TOKEN = os.environ.get("METRICOOL_USER_TOKEN")
headers = {"X-Mc-Auth": METRICOOL_USER_TOKEN}
request = urllib.request.Request(target_url, data=body, method=method, headers=headers)
```
--------------------------------
### Map Local Routes to Metricool API Paths
Source: https://help.metricool.com/wli-setting-up-the-sample-backend-proxy-nc0fs
Implement logic to map local API routes to the corresponding remote Metricool paths, including versioned endpoints and generic fallbacks.
```python
if path == "/api/scheduler/posts":
remote_path = "/v2/scheduler/posts"
elif path.startswith("/api/"):
remote_path = path[len("/api"):]
```
--------------------------------
### Claude Desktop config for Metricool MCP with OAuth
Source: https://help.metricool.com/how-to-connect-metricools-mcp-with-claude-0l84v
Add this JSON to the Claude Desktop config file to connect Metricool via mcp-remote using OAuth. This configuration does not require an API key; browser authorization is completed when prompted.
```json
{
"mcpServers": {
"metricool-mcp": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://ai.metricool.com/mcp"
]
}
}
}
```
--------------------------------
### Forward Request to Metricool API
Source: https://help.metricool.com/wli-setting-up-the-sample-backend-proxy-nc0fs
Construct the target URL with the query string and forward the request with the required authentication header.
```python
target_url = f"{METRICOOL_API_BASE}{remote_path}"
if parsed.query:
target_url = f"{target_url}?{parsed.query}"
request = urllib.request.Request(
target_url, method="GET",
headers={"X-Mc-Auth": METRICOOL_USER_TOKEN},
)
```
--------------------------------
### Link to brand connections with redirect=/brand-connections and networks parameter
Source: https://help.metricool.com/wli-redirect-parameter-details-mu0f4
An HTML anchor that links to the network-connection screen using an autoin URL with `redirect=/brand-connections` and a `networks` parameter (semicolon-separated list) to pre-filter the screen to specific networks.
```html
My Socials
```
--------------------------------
### PUT /v2/scheduler/posts
Source: https://help.metricool.com/basic-guide-for-api-integration-r97af
Sends multiple posts of a brand to review in bulk.
```APIDOC
## PUT /v2/scheduler/posts
### Description
Sends multiple posts of a brand to review in bulk.
### Method
PUT
### Endpoint
https://app.metricool.com/api/v2/scheduler/posts
### Parameters
No parameters documented in the source.
### Request Example
No request example provided in the source.
### Response
#### Success Response (200)
No response schema provided in the source.
#### Response Example
No response example provided in the source.
```
--------------------------------
### Configure Custom MCP in Cursor
Source: https://help.metricool.com/i-cant-connect-to-metricool-mcp-7qhoi
Add this configuration to your Cursor MCP settings to manually define the Metricool server.
```json
"metricool-mcp": {
"url": "https://ai.metricool.com/mcp",
"type": "http"
}
```
--------------------------------
### Frontend Brand Creation Button and Script
Source: https://help.metricool.com/wli-brand-creation-endpoint-example-on-a-custom-backend-proxy-eql6w
A button and JavaScript function to trigger the brand creation process through a backend proxy, including a user confirmation step.
```html
```
--------------------------------
### POST /api/v2/scheduler/posts
Source: https://help.metricool.com/wli-scheduler-endpoint-example-on-a-custom-backend-proxy-frko7
Creates a scheduled post on Metricool. Requires authentication via X-Mc-Auth header and a body with publicationDate, text, and providers. Supports optional fields for auto-publishing, drafts, media, and network-specific options.
```APIDOC
## POST /api/v2/scheduler/posts
### Description
Creates a scheduled post on Metricool. Requires authentication via X-Mc-Auth header and a body with publicationDate, text, and providers. Supports optional fields for auto-publishing, drafts, media, and network-specific options.
### Method
POST
### Endpoint
https://app.metricool.com/api/v2/scheduler/posts?blogId={blogId}&userId={userId}
### Parameters
#### Path Parameters
- `blogId` (string) - Required - The blog identifier.
- `userId` (string) - Required - The user identifier.
#### Headers
- `Content-Type` (string) - Required - Must be `application/json`.
- `X-Mc-Auth` (string) - Required - Your `userToken`.
#### Request Body
- `publicationDate.dateTime` (string) - Required - ISO local date-time without timezone offset (e.g. `2026-08-01T10:00:00`). Must be in the future.
- `text` (string) - Required - The post's text content.
- `providers` (array) - Required - Target networks, e.g. `[{ "network": "facebook" }]`. Supported values: `facebook`, `instagram`, `twitter`, `linkedin`, `tiktok`, `pinterest`, `youtube`, `gmb`, among others.
- `autoPublish` (boolean) - Optional - `true` publishes directly, `false` leaves it pending.
- `draft` (boolean) - Optional - `true` saves it as a draft.
- `creatorUserMail` (string) - Optional - Email of the user creating the post.
- `media` (array of strings) - Optional - See note on media below.
- `facebookData`, `instagramData`, `twitterData`, ... (object) - Optional - Network-specific options (e.g. `{"type": "POST"}` for Facebook).
- `publicationDate.timezone` (string) - Optional - IANA timezone of the brand/user (e.g. `Europe/Madrid`). If none is added, it is set according to the account's timezone.
- `saveExternalMediaFiles` (boolean) - Optional - Set to `true` if the post includes an image or video.
### Request Example
```json
{
"publicationDate": {
"dateTime": "2026-08-01T10:00:00",
"timezone": "Europe/Madrid"
},
"text": "Yeah, team! This is a scheduled post test for White Label Integration.",
"providers": [
{ "network": "facebook" }
],
"autoPublish": true,
"draft": false,
"shortener": false,
"saveExternalMediaFiles": false,
"creatorUserMail": "me@example.com"
}
```
### Response
#### Success Response (200)
No response schema provided in the source.
#### Response Example
No response example provided in the source.
```
--------------------------------
### POST /v2/scheduler/posts
Source: https://help.metricool.com/wli-scheduling-endpoints-example-on-a-custom-backend-proxy-frko7
Creates a new scheduled post in Metricool. Requires authentication via X-Mc-Auth header and query parameters blogId and userId.
```APIDOC
## POST /v2/scheduler/posts
### Description
Creates a new scheduled post in Metricool. This endpoint is used to schedule posts from your own web app through a backend proxy.
### Method
POST
### Endpoint
`https://app.metricool.com/api/v2/scheduler/posts?blogId={blogId}&userId={userId}`
### Parameters
#### Path Parameters
- None
#### Query Parameters
- **blogId** (string) - Required - The brand/profile identifier.
- **userId** (string) - Required - Your Metricool user identifier.
#### Request Headers
- **Content-Type** (string) - Required - Must be `application/json`.
- **X-Mc-Auth** (string) - Required - Your `userToken`.
#### Request Body
- **publicationDate.dateTime** (string) - Required - ISO local date-time without timezone offset (e.g., `2026-08-01T10:00:00`). Must be in the future.
- **text** (string) - Required - The post's text content.
- **providers** (array) - Required - Target networks, e.g., `[{ "network": "facebook" }]`. Supported values: `facebook`, `instagram`, `twitter`, `linkedin`, `tiktok`, `pinterest`, `youtube`, `gmb`, among others.
- **autoPublish** (boolean) - Optional - `true` publishes directly, `false` leaves it pending.
- **draft** (boolean) - Optional - `true` saves it as a draft.
- **creatorUserMail** (string) - Optional - Email of the user creating the post.
- **media** (array of strings) - Optional - See note on media below.
- **facebookData**, **instagramData**, **twitterData**, ... (object) - Optional - Network-specific options (e.g., `{"type": "POST"}` for Facebook).
- **publicationDate.timezone** (string) - Optional - IANA timezone of the brand/user (e.g., `Europe/Madrid`). If none is added, it is set according to the account's timezone.
- **saveExternalMediaFiles** (boolean) - Optional - Set to `true` if the post includes an image or video.
### Request Example
```json
{
"publicationDate": {
"dateTime": "2026-08-01T10:00:00",
"timezone": "Europe/Madrid"
},
"text": "Yeah, team! This is a scheduled post test for White Label Integration.",
"providers": [
{ "network": "facebook" }
],
"autoPublish": true,
"draft": false,
"shortener": false,
"saveExternalMediaFiles": false,
"creatorUserMail": "me@example.com"
}
```
### Response
#### Success Response (200)
- No explicit response schema provided in the source.
#### Response Example
- No explicit response example provided in the source.
### Error Handling
- **401 Unauthorized**: Missing access key. Add the access token (`userToken`) and the userId into the request call.
- **403 Forbidden** on an `OPTIONS` request: Arbitrary browser calling Metricool's API directly triggers a CORS preflight, which Metricool rejects. Route the call through your own backend proxy.
- **400 Bad Request**: `publicationDate.dateTime` is in the past, or a required field is missing. Make sure the date/time is in the future and that `publicationDate`, `text`, and `providers` are present.
- **Unexpected token '<' ... is not valid JSON** in the browser console: Client code called `response.json()` on an error response that wasn't actually JSON. Read the response with `response.text()` first, then attempt to parse it.
- **Token visible in page source**: `userToken` was placed in client-side HTML/JS. Move all credentials to the backend proxy and read them from environment variables.
```
--------------------------------
### Frontend: Fetch local proxy route without credentials
Source: https://help.metricool.com/wli-integration-architecture-customer-success-approach-xjxku
Used in schedules.html to call the local proxy route /api/scheduler/posts. The frontend never includes the token or Metricool URL; it only calls its own domain, avoiding CORS preflight. The body is sent as JSON.
```javascript
// schedules.html — no credentials, no Metricool URL, just your own domain
const response = await fetch('/api/scheduler/posts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
});
```
--------------------------------
### Authentication Header Configuration
Source: https://help.metricool.com/common-questions-and-errors-when-using-the-api-8x9nq
Required headers for all API requests. Ensure both blogId and userId parameters are included in your request.
```http
X-Mc-Auth: YOUR API TOKEN
Content-Type: application/json
```
--------------------------------
### POST /v2/scheduler/posts
Source: https://help.metricool.com/basic-guide-for-api-integration-r97af
Creates a new scheduled post. Requires a future publication date, post text, and at least one network provider.
```APIDOC
## POST /v2/scheduler/posts
### Description
Creates a new scheduled post with the specified publication date, text, and network providers.
### Method
POST
### Endpoint
https://app.metricool.com/api/v2/scheduler/posts?blogId={blogId}&userId={userId}
### Parameters
#### Query Parameters
- **blogId** (string) - Required - The blog identifier.
- **userId** (string) - Required - The user identifier.
#### Request Body
- **publicationDate** (object) - Required - The publication date and timezone. Must be in the future and in ISO 8601 format with timezone.
- **dateTime** (string) - Required - The date and time in ISO 8601 format, e.g., "2025-07-23T10:00:00".
- **timezone** (string) - Required - The timezone, e.g., "Europe/Madrid".
- **text** (string) - Required - The content of the post.
- **providers** (array) - Required - At least one network provider. Each provider object must include a `network` field, e.g., `{ "network": "facebook" }`.
- **draft** (boolean) - Optional - Set to `true` to save the post as a draft instead of scheduling it.
- **autoPublish** (boolean) - Optional - Enable auto-publishing.
- **firstCommentText** (string) - Optional - Text for the first comment.
- **facebookData** (object) - Optional - Network-specific options for Facebook.
- **instagramData** (object) - Optional - Network-specific options for Instagram.
- **twitterData** (object) - Optional - Network-specific options for Twitter.
- **linkedinData** (object) - Optional - Network-specific options for LinkedIn.
- **pinterestData** (object) - Optional - Network-specific options for Pinterest.
- **youtubeData** (object) - Optional - Network-specific options for YouTube.
- **tiktokData** (object) - Optional - Network-specific options for TikTok.
- **gmbData** (object) - Optional - Network-specific options for Google My Business.
- **threadsData** (object) - Optional - Network-specific options for Threads.
- **blueskyData** (object) - Optional - Network-specific options for Bluesky.
### Request Example
{
"publicationDate": {
"dateTime": "2025-07-23T10:00:00",
"timezone": "Europe/Madrid"
},
"text": "Hello! This is a scheduled post test.",
"providers": [
{ "network": "facebook" }
]
}
### Response
#### Success Response (200)
No response schema provided in the source.
#### Response Example
No response example provided in the source.
```
--------------------------------
### Reference media in post
Source: https://help.metricool.com/basic-guide-for-api-integration-r97af
Include the mediaId in the post request body to attach the previously normalized media.
```json
"media": {
"mediaId": "ID_OF_MEDIA"
}
```
--------------------------------
### Iframe embedding the scheduler with redirect=planner
Source: https://help.metricool.com/wli-redirect-parameter-details-mu0f4
Embeds the Metricool calendar view in an iframe by pointing the `src` to an autoin URL with `redirect=planner`. The iframe opens directly on the scheduling calendar, skipping the default landing screen.
```html
```
--------------------------------
### Backend proxy communication flow
Source: https://help.metricool.com/wli-integration-architecture-customer-success-approach-xjxku
Visual representation of the recommended request flow from the browser through a backend proxy to the Metricool API.
```plaintext
Browser (your frontend) → Your backend (proxy) → Metricool API
```
--------------------------------
### Autoin URL with redirect parameter
Source: https://help.metricool.com/wli-redirect-parameter-details-mu0f4
Shows the general shape of an autoin URL with the `redirect` query parameter. The `[AUTOIN_TOKEN]` identifies the brand, and `redirect` decides which screen opens after login.
```http
https://app.metricool.com/autoin/[AUTOIN_TOKEN]?redirect={destination}
```
--------------------------------
### POST request to scheduler endpoint
Source: https://help.metricool.com/basic-guide-for-api-integration-r97af
The endpoint for scheduling posts requires blogId and userId query parameters.
```plaintext
POST https://app.metricool.com/api/v2/scheduler/posts?blogId={blogId}&userId={userId}
```
--------------------------------
### POST /api/lists/posts/updatepostlist
Source: https://help.metricool.com/add-content-to-an-autolist-using-the-api-q3wl0
Fills an empty slot in an autolist with post text and media. This call must be sent as form-data, not JSON.
```APIDOC
## POST /api/lists/posts/updatepostlist
### Description
Fills an empty slot in an autolist with post text and media. This call must be sent as form-data, not JSON.
### Method
POST
### Endpoint
https://app.metricool.com/api/lists/posts/updatepostlist?userId={userId}&blogId={blogId}
### Parameters
#### Query Parameters
- **userId** (string) - Required - Your Metricool user identifier.
- **blogId** (string) - Required - The brand/profile identifier.
#### Request Body (form-data)
- **listid** (string) - Required - The autolist's internal ID.
- **text** (string) - Required - The post's text content.
- **postid** (string) - Required - The id returned from the create slot call.
- **pictures** (file or array) - Required - Image or video file for the post. When there's no image, send [] to avoid silent failure.
### Response
#### Success Response (200)
- No specific response fields documented.
### Notes
- If pictures is sent blank/empty instead of [], the call returns success and saves the text, but the rest of the update fails silently.
```
--------------------------------
### Media Object Structure
Source: https://help.metricool.com/common-questions-and-errors-when-using-the-api-8x9nq
Format for including the mediaId in your post request.
```json
"media": {
"mediaId": "ID_OF_MEDIA"
}
```
--------------------------------
### POST /v2/settings/brands/connections/anonymous-link
Source: https://help.metricool.com/wli-brand-connections-panel-for-end-clients-through-api-4m5b3
Creates a shareable link that lets whoever holds it connect social accounts to a specific brand. Creating a new link invalidates any previous link for the brand.
```APIDOC
## [POST] /v2/settings/brands/connections/anonymous-link
### Description
Creates a shareable link that lets whoever holds it connect social accounts to a specific brand. Creating a new link invalidates any previous link for the brand.
### Method
POST
### Endpoint
https://app.metricool.com/api/v2/settings/brands/connections/anonymous-link?blogId={blogId}&userId={userId}
### Parameters
#### Query Parameters
- **blogId** (string) - Required - The ID of the brand.
- **userId** (string) - Required - The ID of the user.
### Request Example
No request body is required.
### Response
#### Success Response (200)
- **data.link** (string) - The shareable link.
- **data.expiresAt** (object) - Expiration date and timezone.
#### Response Example
{
"data": {
"link": "https://mtr.cool/AB3XY9Z",
"expiresAt": {
"dateTime": "2026-09-03T13:36:39",
"timezone": "Europe/Madrid"
}
}
}
#### Error Responses
- **403** - The user can't edit the brand, or the plan is below Advanced.
- **500** - The link was created but its expiration date couldn't be read.
```
--------------------------------
### POST /api/v2/scheduler/posts
Source: https://help.metricool.com/wli-common-errors-during-iframe-integration-8b1uz
Endpoint for adding new schedules to the calendar. Requires authentication headers and may return errors for invalid dates, missing fields, or CORS preflight rejection.
```APIDOC
## POST /api/v2/scheduler/posts
### Description
Adds new schedules to the calendar. Requires authentication headers and may return errors for invalid dates, missing fields, or CORS preflight rejection.
### Method
POST
### Endpoint
/api/v2/scheduler/posts
### Parameters
#### Headers
- **X-Mc-Auth** (string) - Required - Access token (userToken)
- **Content-Type** (string) - Required - application/json
- **userId** (string) - Required - User ID
#### Request Body
- **publicationDate** (object) - Required - Must contain a dateTime field in the future.
- **text** (string) - Required - The text content of the post.
- **providers** (array) - Required - List of providers to publish to.
### Response
#### Success Response (200)
- **body** (object) - Successful creation response.
#### Error Responses
- **401 Unauthorized** - Missing access key. Add the access token (userToken) and the userId into the request call.
- **403 Forbidden** on an OPTIONS request - Arbitrary browser calling Metricool's API directly triggers a CORS preflight, which Metricool rejects. Route the call through your own backend proxy.
- **400 Bad Request** - publicationDate.dateTime is in the past, or a required field is missing. Make sure the date/time is in the future and that publicationDate, text, and providers are present.
- **Unexpected token '<' ... is not valid JSON** - Client code called response.json() on an error response that wasn't actually JSON. Read the response with response.text() first, then attempt to parse it.
- **Token visible in page source** - userToken was placed in client-side HTML/JS. Move all credentials to the backend proxy and read them from environment variables.
```
--------------------------------
### PUT /v2/scheduler/posts/{id}/approvals
Source: https://help.metricool.com/basic-guide-for-api-integration-r97af
Approves or rejects a scheduled post.
```APIDOC
## PUT /v2/scheduler/posts/{id}/approvals
### Description
Approves or rejects a scheduled post.
### Method
PUT
### Endpoint
https://app.metricool.com/api/v2/scheduler/posts/{id}/approvals
### Parameters
#### Path Parameters
- **id** (string) - Required - The ID of the scheduled post.
### Request Example
No request example provided in the source.
### Response
#### Success Response (200)
No response schema provided in the source.
#### Response Example
No response example provided in the source.
```
--------------------------------
### General structure of an autoin link
Source: https://help.metricool.com/wli-common-errors-during-iframe-integration-8b1uz
The standard URL structure used to create an iframe in a client's account, requiring a unique White Label token.
```text
https://app.metricool.com/autoin/[WL_TOKEN]?redirect=/planner
```
--------------------------------
### Retrieve blogId via API
Source: https://help.metricool.com/common-questions-and-errors-when-using-the-api-8x9nq
Endpoint to list all brands managed by or shared with the user, which includes the blogId for each entry.
```plaintext
https://app.metricool.com/api/admin/simpleProfiles?userId=YOUR_USER_ID
```
--------------------------------
### Calculated field for monthly follower evolution
Source: https://help.metricool.com/data-studio-followers-difference-zo9l0
A CASE statement to identify the last day of each month, allowing for accurate follower count representation in evolution charts.
```plaintext
CASE
WHEN MONTH(Evolution Date) = 1 and DAY(Evolution Date) = 31 THEN 1
WHEN MONTH(Evolution Date) = 2 and DAY(Evolution Date) = IF(MOD(YEAR(Evolution Date),4)=0 AND MOD(YEAR(Evolution Date),100) != 0 OR MOD(YEAR(Evolution Date),400)=0,29,28) THEN 1
WHEN MONTH(Evolution Date) = 3 and DAY(Evolution Date) = 31 THEN 1
WHEN MONTH(Evolution Date) = 4 and DAY(Evolution Date) = 30 THEN 1
WHEN MONTH(Evolution Date) = 5 and DAY(Evolution Date) = 31 THEN 1
WHEN MONTH(Evolution Date) = 6 and DAY(Evolution Date) = 30 THEN 1
WHEN MONTH(Evolution Date) = 7 and DAY(Evolution Date) = 31 THEN 1
WHEN MONTH(Evolution Date) = 8 and DAY(Evolution Date) = 31 THEN 1
WHEN MONTH(Evolution Date) = 9 and DAY(Evolution Date) = 30 THEN 1
WHEN MONTH(Evolution Date) = 10 and DAY(Evolution Date) = 31 THEN 1
WHEN MONTH(Evolution Date) = 11 and DAY(Evolution Date) = 30 THEN 1
WHEN MONTH(Evolution Date) = 12 and DAY(Evolution Date) = 31 THEN 1
ELSE 0
END
```
--------------------------------
### JSON request body for scheduled posts
Source: https://help.metricool.com/basic-guide-for-api-integration-r97af
The request body must include a future publication date in ISO 8601 format, the post text, and at least one provider network.
```json
{
"publicationDate": {
"dateTime": "2025-07-23T10:00:00",
"timezone": "Europe/Madrid"
},
"text": "Hello! This is a scheduled post test.",
"providers": [
{ "network": "facebook" }
]
}
```
--------------------------------
### ISO 8601 Date Format
Source: https://help.metricool.com/common-questions-and-errors-when-using-the-api-8x9nq
Required format for the publicationDate field, including dateTime and timezone.
```json
"publicationDate": {
"dateTime": "2025-07-23T10:00:00",
"timezone": "Europe/Madrid"
}
```
--------------------------------
### POST anonymous link request
Source: https://help.metricool.com/wli-brand-connections-panel-for-end-clients-through-api-4m5b3
Creates or regenerates the anonymous link for a brand. Returns 200 with the new link, invalidating any previous link. Returns 403 if the user can't edit the brand or the plan is below Advanced, or 500 if the link was created but the expiration date couldn't be read.
```http
POST https://app.metricool.com/api/v2/settings/brands/connections/anonymous-link?blogId={blogId}&userId={userId}
```
--------------------------------
### Set METRICOOL_USER_TOKEN environment variable in PowerShell
Source: https://help.metricool.com/wli-setting-up-the-sample-backend-proxy-nc0fs
Sets the Metricool user token as an environment variable in PowerShell. The proxy reads this token from the environment and attaches it to every forwarded request as the X-Mc-Auth header. Never hardcode the token as a fallback value in the Python code.
```powershell
$env:METRICOOL_USER_TOKEN = "your_token_here"
```
--------------------------------
### PUT /v2/scheduler/posts/{id}
Source: https://help.metricool.com/basic-guide-for-api-integration-r97af
Updates a scheduled post.
```APIDOC
## PUT /v2/scheduler/posts/{id}
### Description
Updates a scheduled post.
### Method
PUT
### Endpoint
https://app.metricool.com/api/v2/scheduler/posts/{id}
### Parameters
#### Path Parameters
- **id** (string) - Required - The ID of the scheduled post.
### Request Example
No request example provided in the source.
### Response
#### Success Response (200)
No response schema provided in the source.
#### Response Example
No response example provided in the source.
```