{
  "info": {
    "_postman_id": "49ee35c4-cb5a-47ba-b8e6-17ddf2b24fcb",
    "name": "Social Fanout API",
    "description": "A secret-free starter collection for the hosted Social Fanout REST API. The included publish requests are dry runs: they validate authentication, connection routing, and plan entitlements without calling a social provider or consuming publish quota. Set the collection variables before use. Change dryRun to false only when you intentionally want to publish to the selected customer-owned destination.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "apikey",
    "apikey": [
      {
        "key": "key",
        "value": "x-api-key",
        "type": "string"
      },
      {
        "key": "value",
        "value": "{{apiKey}}",
        "type": "string"
      },
      {
        "key": "in",
        "value": "header",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://socialfanout.com",
      "type": "string"
    },
    {
      "key": "apiKey",
      "value": "",
      "type": "string"
    },
    {
      "key": "connectionId",
      "value": "",
      "type": "string"
    },
    {
      "key": "platform",
      "value": "bluesky",
      "type": "string"
    },
    {
      "key": "jobId",
      "value": "",
      "type": "string"
    },
    {
      "key": "metricsLimit",
      "value": "50",
      "type": "string"
    }
  ],
  "item": [
    {
      "name": "Service",
      "item": [
        {
          "name": "Liveness",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/health",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "health"
              ]
            },
            "description": "Public process liveness. A 200 response is not proof of provider approval or customer activation."
          },
          "response": []
        },
        {
          "name": "Runtime readiness",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/health/ready",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "health",
                "ready"
              ]
            },
            "description": "Public sanitized runtime and schema readiness. This does not establish a provider approval, an ordinary-customer connection, or sellability."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Discovery",
      "item": [
        {
          "name": "List provider capabilities",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/providers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "providers"
              ]
            },
            "description": "Returns the current provider registry and capability/readiness metadata for the authenticated key. Do not infer availability from a static platform list."
          },
          "response": []
        },
        {
          "name": "List customer-owned connections",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/connections",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "connections"
              ]
            },
            "description": "Lists only connections owned by the authenticated API key. Copy a returned connection id into the connectionId collection variable."
          },
          "response": []
        },
        {
          "name": "List adapter accounts",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/accounts",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "accounts"
              ]
            },
            "description": "Returns the API adapter account view for the authenticated key. For native publishing, prefer the connections endpoint."
          },
          "response": []
        },
        {
          "name": "List connection publishing targets",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/connections/{{connectionId}}/targets",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "connections",
                "{{connectionId}}",
                "targets"
              ]
            },
            "description": "Returns live provider-owned targets for a connection when the provider supports them. For example, Pinterest uses this route for a fresh Board selection."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Publishing preflight",
      "description": "Every request in this folder sets dryRun to true. A dry run creates a diagnostic job receipt but does not call a provider or consume publish quota.",
      "item": [
        {
          "name": "Dry-run one destination",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 202) {",
                  "  const body = pm.response.json();",
                  "  if (body.jobId) pm.collectionVariables.set('jobId', body.jobId);",
                  "}",
                  "pm.test('No provider publish was attempted', function () {",
                  "  if (pm.response.code === 202) pm.expect(pm.response.json().dryRun).to.eql(true);",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "Idempotency-Key",
                "value": "postman-dry-run-single-{{$guid}}",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"accountId\": \"{{connectionId}}\",\n  \"connectionId\": \"{{connectionId}}\",\n  \"platform\": \"{{platform}}\",\n  \"text\": \"Social Fanout Postman dry run\",\n  \"mediaUrls\": [],\n  \"dryRun\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/v1/publish",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "publish"
              ]
            },
            "description": "Validates the selected connection, platform, and entitlement without sending content to a provider or consuming quota. A successful 202 response stores jobId for the job-status request."
          },
          "response": []
        },
        {
          "name": "Dry-run fan-out routing",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "Idempotency-Key",
                "value": "postman-dry-run-fanout-{{$guid}}",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"text\": \"Social Fanout multi-target Postman dry run\",\n  \"mediaUrls\": [],\n  \"dryRun\": true,\n  \"targets\": [\n    {\n      \"platform\": \"{{platform}}\",\n      \"accountId\": \"{{connectionId}}\",\n      \"connectionId\": \"{{connectionId}}\"\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/v1/publish",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "publish"
              ]
            },
            "description": "Validates the targets-array routing contract without provider writes. Add up to 20 truthful customer-owned targets before running."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Receipts",
      "item": [
        {
          "name": "Get one publish job",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/jobs/{{jobId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "jobs",
                "{{jobId}}"
              ]
            },
            "description": "Returns one job owned by the durable API key. This endpoint does not expose the stored original request or API-key id."
          },
          "response": []
        },
        {
          "name": "Read recent post metrics",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/posts/metrics?limit={{metricsLimit}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "posts",
                "metrics"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "{{metricsLimit}}"
                }
              ]
            },
            "description": "Returns a current, non-persisted engagement snapshot for recent published posts owned by the authenticated key. Missing provider fields remain null rather than becoming zero."
          },
          "response": []
        }
      ]
    }
  ]
}
