# Postfjord connector brief

Postfjord plans, writes, schedules and publishes social posts for a brand. This brief tells an agent (Meta Muse, Claude, ChatGPT or your own) how to work in one Postfjord workspace through the REST API. The full machine-readable spec is at https://postfjord.com/openapi.json.

## Base URL and auth

- Base URL: `https://app.postfjord.com/api`
- Every request: `Authorization: Bearer pf_live_...`
- One key = one workspace = one brand. The person creates the key under Settings, Apps in Postfjord (the Meta Muse card) and gives it to you through the agent's secure credential store, never in a chat message.
- The key has one scope. `read`: look, never change. `draft`: create and edit drafts, never give a post a date. `publish`: schedule and publish. Ask the person which scope the key has; a 403 with a message about scope tells you too.
- Send and receive JSON. Errors are `{ "error": "<code>", "message": "..." }` with the HTTP status: 400 invalid argument, 401 bad key, 403 outside the scope or a suspended workspace, 404 not found, 409 wrong state (for example publishing a post that already went out), 429 rate limit (60 requests a minute) or AI budget spent.

## The calls

| Call | What it does |
| --- | --- |
| `GET /v1/workspace` | Name, timezone and plan. Call first. |
| `GET /v1/channels` | Connected accounts: id, platform, status, text limit, formats. |
| `GET /v1/brand` | Tone of voice, rules, themes, hashtags, example posts. Read before writing. |
| `GET /v1/media?limit=` | Images and videos with ids, alt text and tags. |
| `GET /v1/posts?from=&to=&status=` | Posts in a date range (on scheduledAt, both ends included; a bare YYYY-MM-DD is that whole day in the workspace time zone) or by status. |
| `POST /v1/posts` | `{ baseText, channelIds, mediaIds?, link?, targets?, scheduledAt?, pillar? }`. Without scheduledAt it is a draft. |
| `GET /v1/posts/{id}` | One post with per-channel status and permalinks. |
| `PATCH /v1/posts/{id}` | Change fields. `scheduledAt: null` makes a scheduled post a draft again. |
| `POST /v1/posts/{id}/cancel` | Cancel a scheduled post. |
| `DELETE /v1/posts/{id}` | Delete a draft or cancelled post. |
| `GET /v1/posts/{id}/log` | Every publish attempt. |
| `GET /v1/analytics?days=` | How the workspace is doing: followers, posts, likes and comments per channel, the top posts and the best times to post. `days` is 7, 30, 90 or 365. |
| `POST /v1/posts/{id}/publish` | Publish now. Needs the publish scope. Ask the person first. |
| `POST /v1/ai/compose` | Optional: Postfjord's own composer writes a draft in the brand voice, from `{ brief, channels }`. Uses the workspace AI budget. |

Times are UTC ISO 8601 (`2026-10-02T07:30:00Z`). The workspace timezone tells you what "Tuesday morning" means for this brand.

## Recipes

### Draft from an idea

1. `GET /v1/workspace` and `GET /v1/brand`.
2. `GET /v1/channels` and keep the active ones the person named (or all active ones).
3. Write the text in the brand voice: its tone, its rules, its hashtags, under `maxText` for every chosen channel. Instagram needs media: pick from `GET /v1/media` by tags and alt text, or ask.
4. `POST /v1/posts` with `baseText`, `channelIds` and `mediaIds`, no `scheduledAt`.
5. Tell the person it is a draft in their calendar with the post id, and offer to schedule it.

### Plan next week

1. `GET /v1/posts?from=<next Monday 00:00 in the workspace zone, as UTC>&to=<Sunday 23:59>` to see what is already there.
2. `GET /v1/brand` for the themes (pillars) and `GET /v1/posts?status=published&limit=30` for what was posted recently, so the week is varied and nothing repeats.
3. Create three to five drafts with the recipe above, one theme each, and list them with a suggested day and time for each.
4. Only when the person agrees on the times: `PATCH /v1/posts/{id}` with `scheduledAt` per post (publish scope).

### What is coming up

1. `GET /v1/posts?from=<now>&to=<now + 7 days>`.
2. Summarise per day: channel, first line of the text, status. Flag `failed` and `partial` posts and offer `GET /v1/posts/{id}/log` to see why.

## Rules

- Create drafts unless the person clearly asked to schedule or publish. A draft never goes out by itself.
- Never call `publish` without saying what will be published, on which accounts, and getting a yes.
- Write in the brand voice from `GET /v1/brand`, not in a generic one. Keep the brand's rules (for example no discounts in percent, no emoji) even when the person's request does not mention them.
- Respect `maxText` and `linkInText` per channel. On Instagram the link goes in the bio or a comment, not in the text.
- Do not invent media ids. Use ids from `GET /v1/media` or ask for an upload in the app.
- Report the post id and status after every change so the person can find it in Postfjord.
- Follow the house writing standard below. It comes with every `GET /v1/brand` call as `writingRules`, and the brand voice sits on top of it.

## How Postfjord writes

Postfjord's own composer writes to one standard, and the person expects your drafts to read the same way. The text below is what `GET /v1/brand` returns as `writingRules`, copied here so you can read it before your first call. The brand profile can add rules to it, never remove them.

HOUSE WRITING STANDARD. These rules come before every other instruction below and before the brand profile. The brand may add rules, never remove these.

1. No em dashes or en dashes anywhere. Use a comma, a period or a colon. A number range gets a plain hyphen: 3-5 posts.
2. Never use these words and phrases: elevate, unlock, empower, seamless, seamlessly, effortless, effortlessly, robust, leverage, harness, tailored, curated, dive in, deep dive, level up, next level, transform, transforms, journey, ultimately, crucial, designed to, built to, whether you're, whether you are, in conclusion, straightforward, genuinely, game-changer, game changer, delve, supercharge, unleash, holistic, synergy, at your fingertips, always within reach, the way it should be, made for you, revolutionize, cutting-edge, in today's. In other languages, avoid their direct equivalents.
3. Never write "not just X, it is Y" or "this is not about X, it is about Y". Say the thing itself. A contrast is fine when the affirmative leads: "One calendar, not five tabs."
4. Cut hedges: really, very, truly, simply, just, actually, incredibly. Keep one only when the sentence means something else without it.
5. Vary sentence length. Put a three word sentence next to a long one. Even rhythm is the strongest sign that a machine wrote the text.
6. No rule of three. "Faster, smarter, simpler" reads as generated. One beat, or two.
7. Do not end with a summary that restates the text in grander words. End on a concrete detail, or stop.
8. Specifics over adjectives: a number, a name, a time, a place. Never invent one that is not in the brief or the brand profile.
9. At most two emoji, often none. No exclamation mark spam, no words in ALL CAPS.
10. The test for every line: would the owner say this out loud to a customer at the front desk? If it sounds like an ad, write it plainer.
