{
  "info": {
    "name": "Herald API v1",
    "description": "Herald multi-tenant social publishing API. Set the `api_key` and `base_url` collection variables, then run any request.\n\nBase URL: https://api.herald.leiritech.com",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{api_key}}",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "base_url",
      "value": "https://api.herald.leiritech.com"
    },
    {
      "key": "api_key",
      "value": "hld_your_key_here"
    },
    {
      "key": "account_id",
      "value": ""
    },
    {
      "key": "post_id",
      "value": ""
    },
    {
      "key": "media_id",
      "value": ""
    },
    {
      "key": "webhook_id",
      "value": ""
    }
  ],
  "item": [
    {
      "name": "Accounts",
      "item": [
        {
          "name": "Connect account",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/accounts/connect",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "accounts",
                "connect"
              ]
            },
            "description": "Returns a hosted connect_url. Open it in a browser to authorize; the account then binds to your tenant. redirect_url is optional (https).",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"network\": \"facebook\",\n  \"redirect_url\": \"https://your-app.example/connected\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Connect WordPress",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/accounts/wordpress",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "accounts",
                "wordpress"
              ]
            },
            "description": "Self-hosted WordPress via Application Password (no OAuth).",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"site_url\": \"https://blog.example.com\",\n  \"username\": \"admin\",\n  \"app_password\": \"xxxx xxxx xxxx xxxx\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Connect Bluesky",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/accounts/bluesky",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "accounts",
                "bluesky"
              ]
            },
            "description": "Bluesky via App Password (no OAuth).",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"identifier\": \"name.bsky.social\",\n  \"app_password\": \"xxxx-xxxx-xxxx-xxxx\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Connect Mastodon",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/accounts/mastodon",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "accounts",
                "mastodon"
              ]
            },
            "description": "Any Mastodon instance via access token (no OAuth).",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"instance_url\": \"https://mastodon.social\",\n  \"access_token\": \"your-access-token\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "List accounts",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/accounts",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "accounts"
              ]
            }
          }
        },
        {
          "name": "Get account",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/accounts/{{account_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "accounts",
                "{{account_id}}"
              ]
            }
          }
        },
        {
          "name": "Get account stats",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/accounts/{{account_id}}/stats",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "accounts",
                "{{account_id}}",
                "stats"
              ]
            },
            "description": "Latest stored snapshot: followers/follows/media (+reach/profile_views if granted)."
          }
        },
        {
          "name": "Disconnect account",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/accounts/{{account_id}}/disconnect",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "accounts",
                "{{account_id}}",
                "disconnect"
              ]
            }
          }
        },
        {
          "name": "Delete account",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/accounts/{{account_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "accounts",
                "{{account_id}}"
              ]
            }
          }
        }
      ]
    },
    {
      "name": "Media",
      "item": [
        {
          "name": "Upload media",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/media",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "media"
              ]
            },
            "description": "multipart/form-data with a `file` field. Returns {id, public_url, bytes}.",
            "body": {
              "mode": "formdata",
              "formdata": [
                {
                  "key": "file",
                  "type": "file",
                  "src": []
                }
              ]
            }
          }
        }
      ]
    },
    {
      "name": "Posts",
      "item": [
        {
          "name": "Create post \u2014 publish now",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/posts",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "posts"
              ]
            },
            "description": "Instagram requires exactly 1 image. Facebook/LinkedIn image optional. `title` is required when a target is WordPress (text = HTML body).",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"targets\": [\n    \"{{account_id}}\"\n  ],\n  \"text\": \"Launch day! \\u2728\",\n  \"title\": \"\",\n  \"media_ids\": [\n    \"{{media_id}}\"\n  ],\n  \"mode\": \"now\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Create post \u2014 draft",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/posts",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "posts"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"targets\": [\n    \"{{account_id}}\"\n  ],\n  \"text\": \"A draft\",\n  \"media_ids\": [],\n  \"mode\": \"draft\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Create post \u2014 schedule",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/posts",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "posts"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"targets\": [\n    \"{{account_id}}\"\n  ],\n  \"text\": \"Scheduled\",\n  \"media_ids\": [\n    \"{{media_id}}\"\n  ],\n  \"mode\": \"schedule\",\n  \"scheduled_at\": \"2026-12-31T09:00:00Z\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "List posts",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/posts",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "posts"
              ]
            }
          }
        },
        {
          "name": "Get post",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/posts/{{post_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "posts",
                "{{post_id}}"
              ]
            }
          }
        },
        {
          "name": "Get post stats",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/posts/{{post_id}}/stats",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "posts",
                "{{post_id}}",
                "stats"
              ]
            }
          }
        },
        {
          "name": "Edit post (draft/scheduled)",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/posts/{{post_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "posts",
                "{{post_id}}"
              ]
            },
            "description": "Only for unpublished posts. media_ids:[] clears media. scheduled_at only on scheduled.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"text\": \"Edited caption\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Publish draft now",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/posts/{{post_id}}/publish",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "posts",
                "{{post_id}}",
                "publish"
              ]
            }
          }
        },
        {
          "name": "Cancel scheduled post",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/posts/{{post_id}}/cancel",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "posts",
                "{{post_id}}",
                "cancel"
              ]
            }
          }
        },
        {
          "name": "Delete post (unpublished)",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/posts/{{post_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "posts",
                "{{post_id}}"
              ]
            }
          }
        },
        {
          "name": "Unpublish (delete live post)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/posts/{{post_id}}/unpublish",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "posts",
                "{{post_id}}",
                "unpublish"
              ]
            },
            "description": "Facebook/LinkedIn delete the live post; Instagram returns unsupported. Omit `targets` to unpublish all live targets.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"targets\": [\n    \"{{account_id}}\"\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Retry failed targets",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/posts/{{post_id}}/retry",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "posts",
                "{{post_id}}",
                "retry"
              ]
            }
          }
        }
      ]
    },
    {
      "name": "Webhooks",
      "item": [
        {
          "name": "Create webhook",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/webhooks",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "webhooks"
              ]
            },
            "description": "Returns `secret` ONCE. Deliveries are HMAC-SHA256 signed with it (X-Herald-Signature: sha256=\u2026).",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"url\": \"https://your-app.example/herald/hooks\",\n  \"events\": [\n    \"post.published\",\n    \"post.failed\",\n    \"account.connected\"\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "List webhooks",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/webhooks",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "webhooks"
              ]
            }
          }
        },
        {
          "name": "Delete webhook",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/webhooks/{{webhook_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "webhooks",
                "{{webhook_id}}"
              ]
            }
          }
        }
      ]
    },
    {
      "name": "Utility",
      "item": [
        {
          "name": "Whoami",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/me",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "me"
              ]
            }
          }
        },
        {
          "name": "Usage",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/usage?days=30",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "usage"
              ],
              "query": [
                {
                  "key": "days",
                  "value": "30"
                }
              ]
            },
            "description": "Per-network publish/failure counts over the last N days."
          }
        }
      ]
    }
  ]
}