Privacy and analytics

We use necessary technical cookies and, only with your consent, analytics and marketing pixels to improve the website and measure campaigns.

Privacy policyCookie policy
Docs
English
EspañolEnglishFrançaisDeutschItalianoPortuguês

Getting started

  • What is Nömad?
  • Getting started with Nömad
  • Create your brand and complete the Genome
  • Invite your team
  • Glossary

Brand OS

  • What is inside Brand OS
  • What is the Genome?
  • Who is Nödo?
  • Talk to Nödo: voice, cards and ordering from the Store
  • Conversations: your team and Nödo
  • What does a Brand Manager do?
  • Brand Kit and Library
  • Posts and calendar
  • Connections
  • Meetings
  • Files we send you with NödoTransfer
  • Your quotes

Work

  • Work and tasks
  • Ordering work
  • Following, reviewing and approving deliveries
  • Approving the posts Nömad prepares
  • Custom quotes
  • Brand history
  • Yes, there are humans behind it

Account and billing

  • Plans and pricing
  • Billing and payments
  • Paying from the apps (iPhone and Android)
  • People and access
  • Organization and brand roles
  • Workspaces and multiple brands
  • Your name and @username
  • Languages, apps and data
  • Leave, close or delete: account, brands and workspaces
  • Delete and restore: what goes and what stays
  • Inbox and notifications: how we let you know
  • Push notifications on your phone and browser
  • Nömad emails and your preferences

Help

  • How to get help

API

  • Brand API
    • Errors
    • Permissions and roles
    • Events and webhooks
    • Brand
    • Genome
    • Brand Kit
    • Library
    • Works
    • Calendar
    • Connections
    • Publishing
    • Inbox
    • Team
    • Account and team
    • Conversation
    • Memory
    • Questions
    • Media
    • Store
    • Plan
    • Orders
    • Activity
    • Workspace
    • Your account
    • Billing
    • Sync
    • Website and domains
    • Statistics
    • Events

MCP

  • MCP server

Connectors

  • Brand connectors

Nödo and agents

  • Nödo in the brand

Genome

  • Genome specification
API/Brand API
Reference43 min read

Publishing

Drafts and scheduling on social networks.

On this page
  • publishing.posts.list · List posts
  • publishing.posts.get · Get a post
  • publishing.posts.draft · Draft a post
  • publishing.posts.request_review · Request review
Русский
한국어
日本語
中文
हिन्दी
Open the app
  • publishing.posts.schedule · Propose a publish time
  • publishing.accounts.list · Publishing accounts
  • publishing.formats.describe · Format rules
  • publishing.metrics.get · Post metrics
  • publishing.ideas.create · Save an idea
  • publishing.ideas.list · List ideas
  • publishing.mentions.suggest · Suggest mentions
  • publishing.networks.list · Networks and formats
  • publishing.posts.save · Save a post
  • publishing.variants.schedule · Schedule or publish now
  • publishing.reviews.request · Request approval
  • publishing.reviews.decide · Decide a review
  • publishing.comments.add · Comment on a post
  • publishing.posts.mutate · Cancel or retry posts
  • publishing.variants.mutate · Cancel, retry or complete destinations
  • publishing.variants.mark_published · Mark as published
  • publishing.posts.delete · Delete posts
  • publishing.posts.duplicate · Duplicate posts
  • publishing.posts.start_work · Start a post
  • publishing.planned.bind · Bind planned destinations
  • publishing.remote.delete · Delete from the network
  • publishing.media.prepare · Prepare files for publishing
  • publishing.media.start_job · Start a media job
  • publishing.media.accept_derivative · Accept a derived file
  • publishing.settings.configure_policy · Configure the approval policy
  • publishing.settings.configure_queue · Configure an account queue
  • publishing.settings.pause · Pause or resume publishing
  • publishing.queue.reorder · Reorder a queue
  • publishing.external_reviews.issue_links · Issue client review links
  • publishing.external_reviews.revoke_link · Revoke a client review link
  • publishing.history.rerun_import · Re-import post history
  • publishing.calendar.reschedule · Reschedule from the calendar
  • publishing.calendar.swap · Swap two schedules
  • publishing.calendar.duplicate · Duplicate a post
  • publishing.agency.accept · Accept a post from Nömad
  • publishing.agency.accept_with_changes · Accept with changes
  • publishing.agency.request_changes · Request changes from Nömad
  • publishing.agency.record_approval · Record an approval
  • publishing.approval_links.create · Send for approval
  • publishing.approval_links.revoke · Revoke an approval link
  • publishing.writer.topics · Propose topics with Nödo
  • publishing.writer.compose · Write with Nödo
  • publishing.writer.refine · Refine with Nödo
  • publishing.writer.adapt · Adapt per network with Nödo
  • publishing.writer.mark_assisted · Record Nödo assistance
  • publishing.editorial_plan.save_rhythm · Save the editorial rhythm
  • publishing.editorial_plan.save_month · Save the editorial month
  • publishing.editorial_plan.improve · Improve the plan with Nödo
  • publishing.editorial_plan.propose_rebalance · Rebalance the month with Nödo
  • publishing.editorial_plan.approve · Approve the editorial plan
  • publishing.themes.update · Edit a theme
  • publishing.themes.delete · Delete a theme
  • publishing.themes.restore · Restore a theme
  • publishing.themes.create · Add a theme
  • publishing.themes.generate · Generate the theme bank
  • publishing.themes.reset_status · Unblock the theme generation
  • publishing.posts.awaiting · Posts awaiting the brand
  • publishing.editorial_plan.board · Read the editorial plan
  • publishing.posts.list · List posts

    The brand's posts with their real state, derived from their destinations (one per connected account): draft, in_review, approved_unscheduled, scheduled, publishing, published, partial, failed (blocked, failed, missed or uncertain: needs a person), deleted (every published destination was removed from its network since) or cancelled. Filter by status, accountId, source and a from/to window on the planned or actual publish time. Each destination carries its scheduled time, permalink and latest metrics. Use publishing.posts.get for the copy and media of one post.

    FieldValue
    KindRead
    HTTP methodPOST /api/v1/publishing.posts.list
    MCP toolpublishing_posts_list
    Scopepublishing.read
    Minimum roleViewer
    Human confirmationNo
    DoorsNödo, Voice, MCP, API, Chat, Screens, Apps
    StatusAvailable
    Widgetlist

    Input

    {
      status?: "all" | "draft" | "in_review" | "approved_unscheduled" | "scheduled" | "published" | "failed" | "deleted" | "cancelled"  // default "all" · A post matches every state one of its destinations is in; `published` includes partially published posts and excludes destinations deleted from their network, which match `deleted`.
      accountId?: string  // uuid
      source?: "person" | "agent"
      from?: string  // date-time
      to?: string  // date-time
      cursor?: string  // ≤ 512 · Opaque cursor from a previous `nextCursor`.
      limit?: integer  // 1–50 · default 20
    }

    Output

    {
      items: Array<{
        id: string  // uuid
        title: string | null
        status: "draft" | "in_review" | "approved_unscheduled" | "scheduled" | "publishing" | "published" | "partial" | "failed" | "deleted" | "cancelled"
        channels: string[]
        scheduledAt: string | null  // Earliest planned or proposed time among the destinations.
        publishedAt: string | null  // Latest confirmed publication among the destinations.
        source: "person" | "agent"  // `agent` when an agent drafted it for a person.
        destinations: Array<{
          variantId: string  // uuid
          accountId: string  // uuid · Connected account id, as `publishing.accounts.list` returns it.
          network: string  // Network key: instagram, facebook_pages, threads, linkedin, tiktok, youtube, x, pinterest, bluesky, google_business_profile, wordpress, mailerlite.
          account: string | null
          format: string
          status: string  // Raw destination status: draft, in_review, approved, scheduled, preparing, publishing, processing, published, manual_pending, manual_confirmed, missed, blocked, failed, uncertain or cancelled; `deleted` when it was published and later removed from the network (from Nömad or in the network itself).
          scheduledAt: string | null
          publishedAt: string | null
          permalink: string | null  // Public link on the network; null once the post was deleted there.
          deletedAt?: string | null  // When a published destination was found deleted from its network.
          metrics: {
            observedAt: string
            values: Record<string, number>  // Latest counters the network reports (likes, comments, views…); keys vary per network.
          }
          | null
        }>
        reviewUrl: string  // uri · Where a person reviews, approves or edits the post in Nömad. Show it to them.
        updatedAt: string
      }>
      nextCursor: string | null
    }

    publishing.posts.get · Get a post

    One post in full: base copy, each destination with its own copy, format, media (with an in-app preview link), schedule, review requests and decisions, delivery attempts, permalink and latest metrics. revision is what publishing.posts.draft needs as expectedRevision to edit it.

    FieldValue
    KindRead
    HTTP methodPOST /api/v1/publishing.posts.get
    MCP toolpublishing_posts_get
    Scopepublishing.read
    Minimum roleViewer
    Human confirmationNo
    DoorsNödo, Voice, MCP, API, Chat, Screens, Apps
    StatusAvailable
    Widgetrecord

    Input

    {
      postId: string  // uuid
    }

    Output

    {
      id: string  // uuid
      title: string | null
      status: "draft" | "in_review" | "approved_unscheduled" | "scheduled" | "publishing" | "published" | "partial" | "failed" | "deleted" | "cancelled"
      channels: string[]
      scheduledAt: string | null  // Earliest planned or proposed time among the destinations.
      publishedAt: string | null  // Latest confirmed publication among the destinations.
      source: "person" | "agent"  // `agent` when an agent drafted it for a person.
      destinations: Array<{
        variantId: string  // uuid
        accountId: string  // uuid · Connected account id, as `publishing.accounts.list` returns it.
        network: string  // Network key: instagram, facebook_pages, threads, linkedin, tiktok, youtube, x, pinterest, bluesky, google_business_profile, wordpress, mailerlite.
        account: string | null
        format: string
        status: string  // Raw destination status: draft, in_review, approved, scheduled, preparing, publishing, processing, published, manual_pending, manual_confirmed, missed, blocked, failed, uncertain or cancelled; `deleted` when it was published and later removed from the network (from Nömad or in the network itself).
        scheduledAt: string | null
        publishedAt: string | null
        permalink: string | null  // Public link on the network; null once the post was deleted there.
        deletedAt?: string | null  // When a published destination was found deleted from its network.
        metrics: {
          observedAt: string
          values: Record<string, number>  // Latest counters the network reports (likes, comments, views…); keys vary per network.
        }
        | null
        title: string
        text: string
        inheritsText: boolean
        deliveryMethod: "direct" | "manual"
        options: Record<string, unknown>
        media: Array<{
          fileId: string  // uuid
          name: string | null
          mimeType: string | null
          role: string
          altText: string | null
          previewUrl: string | null  // In-app thumbnail; opens for people signed in to the brand.
        }>
        schedule: {
          kind: string
          at: string | null
          timezone: string
          status: string
        }
        | null
        delivery: {
          jobStatus: string | null
          attempts: integer  // -9007199254740991–9007199254740991
          lastError: string | null
          updatedAt: string | null
        }
      }>
      reviewUrl: string  // uri · Where a person reviews, approves or edits the post in Nömad. Show it to them.
      updatedAt: string
      baseText: string
      tags: string[]
      revision: integer  // -9007199254740991–9007199254740991
      createdAt: string
      createdBy: {
        id: string  // uuid
        name: string | null
      }
      | null
      via: {
        door: string
        clientId: string | null
        model: string | null
      }
      | null  // Which agent drafted it, when one did.
      review: {
        policy: "none" | "internal" | "internal_client"
        agentPolicy: "never" | "review"
        requests: Array<{
          id: string  // uuid
          accountId: string | null
          stage: "internal" | "client"
          status: string
          createdAt: string
          decisions: Array<{
            decision: string
            comment: string | null
            decidedAt: string | null
          }>
        }>
      }
    }

    publishing.posts.draft · Draft a post

    Creates, in one call, a draft post for several connected accounts: base copy, optional per-destination copy, format and options, and approved Library files (ids from library.search). It always stays a draft, marked as written by an agent for the person you act for, and returns reviewUrl for them plus, per destination, the format issues (issues) and the brand voice check of its copy (brandCheck). It never publishes or schedules; then call publishing.posts.request_review or publishing.posts.schedule so a person decides. Read the limits first with publishing.formats.describe. Pass postId + expectedRevision to rewrite a draft nobody has been asked to review yet.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.posts.draft
    MCP toolpublishing_posts_draft
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsNödo, MCP, API, Chat, Screens, Apps
    StatusAvailable
    Widgetrecord

    Input

    {
      postId?: string  // uuid
      expectedRevision?: integer  // –9007199254740991 · Required with `postId`: the `revision` from `publishing.posts.get`.
      title: string  // ≤ 200 · Name of the post in Nömad. Networks with a title field (YouTube, Pinterest, articles) use it unless a destination sets its own `title`.
      text: string  // ≤ 10000 · Base copy every destination uses unless it sets its own `text`.
      tags?: string[]  // ≤ 20 items · default []
      fileIds?: string[]  // ≤ 10 items · default [] · Approved Library files attached to every destination that does not list its own.
      destinations: Array<{
        accountId: string  // uuid
        format: "text" | "image" | "carousel" | "video" | "reel" | "story" | "document" | "poll" | "article" | "event" | "offer" | "campaign"
        text?: string  // ≤ 10000 · Copy for this network only; omit to use the base copy.
        title?: string  // ≤ 500 · Title where the network has one (YouTube, Pinterest, articles).
        fileIds?: string[]  // ≤ 20 items
        options?: Record<string, string | number | boolean>  // Network options from `publishing.formats.describe`, e.g. { "privacyStatus": "unlisted" }.
      }>  // ≤ 12 items
      idempotencyKey?: string  // ≤ 120 · Any unique string you choose per intended draft. Retrying with the same key returns the first result instead of a duplicate.
      agentModel?: string  // ≤ 80 · Your model name (e.g. claude-opus-4). Recorded as self-reported next to the post, so reviewers know what wrote it.
    }

    Output

    {
      ok: true
      id: string  // uuid
      title: string
      revision: integer  // -9007199254740991–9007199254740991
      status: "draft"
      replayed: boolean  // True when `idempotencyKey` matched an earlier call and nothing new was created.
      readyForReview: boolean  // No blocking issue: it can be sent to review.
      issues: Array<{
        accountId: string | null
        field: string
        code: string  // Stable key, e.g. text_too_long, media_count_invalid, media_aspect_invalid, format_unavailable, media_check_pending, direct_publishing_unavailable. Account warnings: connection_broken, missing_permissions, connection_paused and expires_before_post (params `cause`, `renewBy`): the account needs reconnecting before the post goes out; tell the person which one and why.
        severity: "error" | "warning"  // Errors must be fixed before review; warnings only inform.
        params?: Record<string, string | number>
      }>
      brandCheck: Array<{
        accountId: string  // uuid
        ok: boolean  // False when the text breaks a blocking brand or sector rule.
        findings: Array<{
          ruleId: string
          source: string  // `brand` for the Genome rules, otherwise the sector pack.
          severity: "block" | "warn"
          match: string
          message: {
            es: string
            en: string
          }
          suggestion?: string
        }>
      }>
      mentionSuggestions?: Array<{
        network: string  // Network key the handle belongs to (instagram, threads, x, tiktok, bluesky, facebook_pages, linkedin, youtube).
        handle: string  // Username without the @.
        name: string | null  // Public display name, when a lookup found the account.
        verified: boolean  // An official lookup found this public account recently.
        uses: integer  // -9007199254740991–9007199254740991 · Times the brand used it in posts, collaborators, tags or its imported history.
        lastUsedAt: string | null
        reason: "named_in_text" | "handle_in_text" | "used_before"  // `named_in_text`: the account's name appears in the text without its @handle; `handle_in_text`: its handle appears without the @; `used_before`: the brand mentioned, tagged or collaborated with it before.
        accountId: string  // uuid
      }>  // Accounts the brand used before that the copy names without their @handle, per destination. Only proposals: tell the person and let them add the mention; never rewrite the draft on your own.
      reviewUrl: string  // uri · Where a person reviews, approves or edits the post in Nömad. Show it to them.
    }

    publishing.posts.request_review · Request review

    Sends a draft to review so a person decides: the brand's configured reviewers, or its owners and admins when none are set. It never approves or publishes, even when you act for an owner, and agents can never skip review. If a destination still has blocking issues nothing changes and state is needs_changes. Returns reviewUrl: share it so they approve there. To also propose a time, use publishing.posts.schedule instead.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.posts.request_review
    MCP toolpublishing_posts_request_review
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsNödo, MCP, API, Chat, Screens, Apps
    StatusAvailable
    Widgetrecord

    Input

    {
      postId: string  // uuid
      accountIds?: string[]  // ≤ 12 items · Account ids of the destinations to send; omit for every destination still in draft.
    }

    Output

    {
      ok: true
      id: string  // uuid
      title: string
      state: "in_review" | "needs_changes"  // `needs_changes`: nothing changed; fix `issues` (errors) and ask again.
      proposedAt: string | null  // Time proposed to the reviewer; it only takes effect if a person approves.
      timezone: string | null
      reviewers: integer  // -9007199254740991–9007199254740991 · People asked to decide.
      agentPolicy: "never" | "review"  // Brand rule for agent posts. `never` (default): a person always approves an agent post.
      issues: Array<{
        accountId: string | null
        field: string
        code: string  // Stable key, e.g. text_too_long, media_count_invalid, media_aspect_invalid, format_unavailable, media_check_pending, direct_publishing_unavailable. Account warnings: connection_broken, missing_permissions, connection_paused and expires_before_post (params `cause`, `renewBy`): the account needs reconnecting before the post goes out; tell the person which one and why.
        severity: "error" | "warning"  // Errors must be fixed before review; warnings only inform.
        params?: Record<string, string | number>
      }>
      reviewUrl: string  // uri · Where a person reviews, approves or edits the post in Nömad. Show it to them.
    }

    publishing.posts.schedule · Propose a publish time

    Proposes a publish time and sends the draft to review in one step. Nothing is scheduled until a person approves it in Nömad; the approval then schedules it at that time (if the time has passed by then, it is marked missed). Agents never schedule or publish directly. publishAt must be in the future; timezone (IANA) defaults to the brand's publishing timezone. Returns reviewUrl for the approver.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.posts.schedule
    MCP toolpublishing_posts_schedule
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsNödo, MCP, API, Chat, Screens, Apps
    StatusAvailable
    Widgetrecord

    Input

    {
      postId: string  // uuid
      publishAt: string  // date-time
      timezone?: string  // ≤ 100
      accountIds?: string[]  // ≤ 12 items · Account ids of the destinations to send; omit for every destination still in draft.
    }

    Output

    {
      ok: true
      id: string  // uuid
      title: string
      state: "in_review" | "needs_changes"  // `needs_changes`: nothing changed; fix `issues` (errors) and ask again.
      proposedAt: string | null  // Time proposed to the reviewer; it only takes effect if a person approves.
      timezone: string | null
      reviewers: integer  // -9007199254740991–9007199254740991 · People asked to decide.
      agentPolicy: "never" | "review"  // Brand rule for agent posts. `never` (default): a person always approves an agent post.
      issues: Array<{
        accountId: string | null
        field: string
        code: string  // Stable key, e.g. text_too_long, media_count_invalid, media_aspect_invalid, format_unavailable, media_check_pending, direct_publishing_unavailable. Account warnings: connection_broken, missing_permissions, connection_paused and expires_before_post (params `cause`, `renewBy`): the account needs reconnecting before the post goes out; tell the person which one and why.
        severity: "error" | "warning"  // Errors must be fixed before review; warnings only inform.
        params?: Record<string, string | number>
      }>
      reviewUrl: string  // uri · Where a person reviews, approves or edits the post in Nömad. Show it to them.
    }

    publishing.accounts.list · Publishing accounts

    Connected accounts the brand can publish to, with their health: credentials ok, expiring (within 7 days) or expired, whether Nömad may publish to that network by API yet (directPublishing, with reasons when not), the formats each accepts, its timezone and whether it is paused. Also the brand's review rule (approvalPolicy) and agent rule (agentPolicy). Use it to get the accountIds for a draft.

    FieldValue
    KindRead
    HTTP methodPOST /api/v1/publishing.accounts.list
    MCP toolpublishing_accounts_list
    Scopepublishing.read
    Minimum roleViewer
    Human confirmationNo
    DoorsNödo, Voice, MCP, API, Chat, Screens, Apps
    StatusAvailable
    Widgetlist

    Input

    {}

    Output

    {
      publishingActive: boolean  // False while Nömad's publisher is switched off: drafts and reviews still work.
      paused: boolean
      approvalPolicy: "none" | "internal" | "internal_client"
      agentPolicy: "never" | "review"
      items: Array<{
        accountId: string  // uuid
        network: string
        name: string
        handle: string | null
        status: "connected" | "needs_attention"
        credentials: "ok" | "expiring" | "expired" | "error"
        credentialsExpireAt: string | null
        gateActive: boolean  // Nömad has certified API publishing for this network.
        directPublishing: boolean
        reasons: string[]
        formats: string[]
        timezone: string | null
        paused: boolean
      }>
    }

    publishing.formats.describe · Format rules

    What each format accepts on each connected account, from Nömad's catalogue of network rules: text limit and its unit (characters, UTF-16 units, bytes, graphemes…), number and type of files, size, aspect ratio, duration, options, and whether it can be published by API. Read it before drafting so the copy fits; omit both filters for every account.

    FieldValue
    KindRead
    HTTP methodPOST /api/v1/publishing.formats.describe
    MCP toolpublishing_formats_describe
    Scopepublishing.read
    Minimum roleViewer
    Human confirmationNo
    DoorsNödo, Voice, MCP, API, Chat, Screens, Apps
    StatusAvailable

    Input

    {
      accountId?: string  // uuid
      format?: "text" | "image" | "carousel" | "video" | "reel" | "story" | "document" | "poll" | "article" | "event" | "offer" | "campaign"
    }

    Output

    {
      items: Array<{
        accountId: string  // uuid
        network: string
        account: string | null
        format: "text" | "image" | "carousel" | "video" | "reel" | "story" | "document" | "poll" | "article" | "event" | "offer" | "campaign"
        status: "verified" | "candidate" | "unsupported" | "retired"  // `verified`: checked against the network documentation; `candidate`: not certified yet.
        directPublishing: boolean  // True when Nömad can publish this format on this account by API once approved; otherwise a person publishes it by hand.
        text: {
          required: boolean
          max: integer | null
          unit: "characters" | "code_points" | "utf16_units" | "utf8_bytes" | "graphemes" | "threads_weighted" | "x_weighted" | null
        }
        media: {
          min: integer  // -9007199254740991–9007199254740991
          max: integer | null
          mimeTypes: string[]
          maxBytes: number | null
          rules: Record<string, unknown>  // Every other media rule as the catalogue states it: aspect [min,max] (width/height), duration [min,max] seconds, width, fps, codecs, cover.
        }
        options: string[]  // Network options a destination may set in `options`.
        notes: string[]  // Known limits not checked automatically.
      }>
    }

    publishing.metrics.get · Post metrics

    Latest metrics of what was published, per post and summed per account: posts published through Nömad and, where imported, the account's earlier history. Filter by postId, accountId and a from/to publish date. Values are the counters each network reports (keys vary); availability says why one is missing. Use it to say what worked before proposing new posts.

    FieldValue
    KindRead
    HTTP methodPOST /api/v1/publishing.metrics.get
    MCP toolpublishing_metrics_get
    Scopepublishing.read
    Minimum roleViewer
    Human confirmationNo
    DoorsNödo, Voice, MCP, API, Chat, Screens, Apps
    StatusAvailable

    Input

    {
      postId?: string  // uuid
      accountId?: string  // uuid
      from?: string
      to?: string
      limit?: integer  // 1–50 · default 20
    }

    Output

    {
      items: Array<{
        origin: "nomad" | "history"  // `history`: published outside Nömad and imported.
        postId: string | null
        variantId: string | null
        accountId: string | null
        network: string | null
        permalink: string | null
        publishedAt: string | null
        observedAt: string | null
        values: Record<string, number>
        availability: Record<string, string>
      }>
      totals: Array<{
        accountId: string | null
        network: string | null
        posts: integer  // -9007199254740991–9007199254740991
        values: Record<string, number>
      }>
    }

    publishing.ideas.create · Save an idea

    Saves a post idea (title, text, tags, approved Library files) in the brand's Ideas, marked as proposed by an agent. An idea is a post in its first stage: no networks, no date, no work. A person decides whether to turn it into a post, which keeps the same id. Retrying with the same idempotencyKey returns the first idea.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.ideas.create
    MCP toolpublishing_ideas_create
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsNödo, MCP, API, Chat, Screens, Apps
    StatusAvailable

    Input

    {
      title: string  // ≤ 200
      text?: string  // ≤ 10000 · default ""
      tags?: string[]  // ≤ 20 items · default []
      fileIds?: string[]  // ≤ 10 items · default []
      idempotencyKey?: string  // ≤ 120 · Any unique string you choose per intended draft. Retrying with the same key returns the first result instead of a duplicate.
      agentModel?: string  // ≤ 80 · Your model name (e.g. claude-opus-4). Recorded as self-reported next to the post, so reviewers know what wrote it.
    }

    Output

    {
      ok: true
      id: string  // uuid
      revision: integer  // -9007199254740991–9007199254740991
      replayed: boolean
      url: string  // uri
    }

    publishing.ideas.list · List ideas

    Saved post ideas of the brand, newest first, with who proposed them (person or agent). An idea turned into a post leaves this list and keeps its id among the posts (publishing.posts.list). Check both before proposing the same idea twice.

    FieldValue
    KindRead
    HTTP methodPOST /api/v1/publishing.ideas.list
    MCP toolpublishing_ideas_list
    Scopepublishing.read
    Minimum roleViewer
    Human confirmationNo
    DoorsNödo, Voice, MCP, API, Chat, Screens, Apps
    StatusAvailable
    Widgetlist

    Input

    {
      cursor?: string  // ≤ 512 · Opaque cursor from a previous `nextCursor`.
      limit?: integer  // 1–50 · default 20
    }

    Output

    {
      items: Array<{
        id: string  // uuid
        title: string
        text: string
        tags: string[]
        source: "person" | "agent"
        convertedPostId: string | null  // Always null: an idea is a post in status `idea`, and turning it into a post keeps its id (it then appears in `publishing.posts.list`). Kept for compatibility.
        createdAt: string
      }>
      nextCursor: string | null
    }

    publishing.mentions.suggest · Suggest mentions

    Accounts the brand already mentioned, tagged or invited as collaborators (from its Nömad posts and imported history), per network, ranked by how often and how recently. Pass text to get only the accounts that text names without their @handle (e.g. «with Café Vómer» → @cafevomer); pass query to filter by handle or name. No network lets apps list followers, so this is the brand's own directory, not a search of the network. Only suggest: tell the person which mentions fit and let them add them; never insert them into a draft yourself.

    FieldValue
    KindRead
    HTTP methodPOST /api/v1/publishing.mentions.suggest
    MCP toolpublishing_mentions_suggest
    Scopepublishing.read
    Minimum roleViewer
    Human confirmationNo
    DoorsNödo, Voice, MCP, API, Chat, Screens, Apps
    StatusAvailable

    Input

    {
      network?: string  // Only this network (instagram, threads, x, tiktok, bluesky, facebook_pages, linkedin, youtube).
      text?: string  // ≤ 10000 · Copy to check for names written without their @handle.
      query?: string  // ≤ 120 · Filter by the start of a handle or name.
      limit?: integer  // 1–20 · default 8
    }

    Output

    {
      items: Array<{
        network: string  // Network key the handle belongs to (instagram, threads, x, tiktok, bluesky, facebook_pages, linkedin, youtube).
        handle: string  // Username without the @.
        name: string | null  // Public display name, when a lookup found the account.
        verified: boolean  // An official lookup found this public account recently.
        uses: integer  // -9007199254740991–9007199254740991 · Times the brand used it in posts, collaborators, tags or its imported history.
        lastUsedAt: string | null
        reason: "named_in_text" | "handle_in_text" | "used_before"  // `named_in_text`: the account's name appears in the text without its @handle; `handle_in_text`: its handle appears without the @; `used_before`: the brand mentioned, tagged or collaborated with it before.
      }>
    }

    publishing.networks.list · Networks and formats

    What each network Nömad publishes to is, connected or not: its formats, how many files of which kind each takes, the recommended aspect ratio, the text limit and the unit it is counted in (characters, X-weighted, UTF-16 units, bytes, graphemes), and its hashtag policy. For a connected account's certified rules use publishing.formats.describe.

    FieldValue
    KindRead
    HTTP methodPOST /api/v1/publishing.networks.list
    MCP toolpublishing_networks_list
    Scopepublishing.read
    Minimum roleViewer
    Human confirmationNo
    DoorsNödo, Voice, MCP, API, Chat, Screens, Apps
    StatusAvailable

    Input

    {
      network?: string  // Only this network (instagram, facebook_pages, threads, linkedin, x, tiktok, youtube, pinterest, bluesky, google_business_profile…).
    }

    Output

    {
      items: Array<{
        network: string
        label: string
        family: "social" | "video" | "local" | "web" | "email"
        clickableLinks: boolean
        mentions: boolean
        hashtags: {
          max: integer  // -9007199254740991–9007199254740991
          placement: "end" | "inline" | "none"
        }
        formats: Array<{
          format: "text" | "image" | "carousel" | "video" | "reel" | "story" | "document" | "poll" | "article" | "event" | "offer" | "campaign"
          media: {
            kind: "none" | "image" | "video" | "image_or_video" | "mixed" | "document"
            min: integer  // -9007199254740991–9007199254740991
            max: integer  // -9007199254740991–9007199254740991
            maxSeconds?: number
          }
          recommendedAspect: string  // Width:height to create files at, e.g. 4:5 or 9:16.
          aspectRange: array  // ≤ 2 items · Width / height the network accepts or crops to.
          textLimit: integer | null
          textUnit: "characters" | "x_weighted" | "threads_weighted" | "utf16" | "utf8_bytes" | "graphemes"
          textRequired: boolean
          titleLimit: integer | null
        }>
      }>
    }

    publishing.posts.save · Save a post

    Creates or saves a post draft with its destinations (send id and expectedVersion to edit). Returns the post, the checks scheduling will apply as guidance, and unscheduled when the edit sent scheduled destinations back to draft. Never schedules or publishes.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.posts.save
    MCP toolpublishing_posts_save
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      draft: Record<string, unknown>  // The composer draft (`PublishingPostDraft`): id and expectedVersion to edit, title, baseText, tags, media and one variant per destination.
    }

    Output

    {
      post: {
        id: string  // uuid
        version: integer  // -9007199254740991–9007199254740991
        variants: Array<{
          id: string  // uuid
          status: string
        }>
      }
      issues: Array<{
        code: string
        field: string
        severity: "error" | "warning"
      }>
      unscheduled: boolean
    }

    publishing.variants.schedule · Schedule or publish now

    Schedules destinations of a post at a fixed time, in the account queue or right now (mode). Idempotent: the same request again changes nothing. With blocking issues it schedules nothing and answers scheduled: false with them. Publishing reaches the public, so agents never run it.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.variants.schedule
    MCP toolpublishing_variants_schedule
    Scopepublishing.write
    Minimum roleMember
    Human confirmationYes
    DoorsAPI, Screens, Apps
    StatusAvailable

    Input

    {
      schedule: Record<string, unknown>  // `PublishingScheduleInput`: postId, variantIds, expectedVersion, mode (fixed | queue | now), scheduledAt, timezone.
    }

    Output

    {
      scheduled: boolean
      post: {
        id: string  // uuid
        version: integer  // -9007199254740991–9007199254740991
        variants: Array<{
          id: string  // uuid
          status: string
        }>
      }
      | null
      issues: Array<{
        code: string
        field: string
        severity: "error" | "warning"
      }>
    }

    publishing.reviews.request · Request approval

    Sends destinations of a post for approval under the brand policy and notifies the reviewers. With blocking issues it sends nothing and answers requested: false with them. Returns the post reviews.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.reviews.request
    MCP toolpublishing_reviews_request
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      postId: string  // uuid
      variantIds: string[]  // ≤ 50 items
    }

    Output

    {
      requested: boolean
      reviews: Record<string, unknown>[]
      issues: Array<{
        code: string
        field: string
        severity: "error" | "warning"
      }>
    }

    publishing.reviews.decide · Decide a review

    Approves or rejects one review request with a comment. Only the brand reviewers decide; Nömad staff never approve for the brand. An approval may release a «publish now».

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.reviews.decide
    MCP toolpublishing_reviews_decide
    Scopepublishing.write
    Minimum roleViewer
    Human confirmationYes
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      requestId: string  // uuid
      decision: "approved" | "rejected"
      comment: string  // ≤ 10000
    }

    Output

    {
      ok: true
    }

    publishing.comments.add · Comment on a post

    Adds a comment to a post thread (internal, client-facing or a Nömad-only note) and notifies who follows it. unreached lists mentioned colleagues who cannot open the brand. Composer cards (inserts) are built on the web only.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.comments.add
    MCP toolpublishing_comments_add
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      postId: string  // uuid
      text: string  // ≤ 10000
      visibility: "internal" | "client" | "nomad"
      mentions?: unknown[]  // ≤ 50 items · default []
      inserts?: unknown[]  // ≤ 20 items · default []
    }

    Output

    {
      comment: Record<string, unknown>
    }

    publishing.posts.mutate · Cancel or retry posts

    Cancels or retries every destination of up to 100 posts. Each destination answers on its own; a refusal never undoes the others. A retry sends to the network again, so agents never run it.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.posts.mutate
    MCP toolpublishing_posts_mutate
    Scopepublishing.write
    Minimum roleMember
    Human confirmationYes
    DoorsAPI, Screens, Apps
    StatusAvailable

    Input

    {
      postIds: string[]  // ≤ 100 items
      action: "cancel" | "retry"
    }

    Output

    {
      results: Array<{
        variantId: string  // uuid
        ok: boolean
        error?: string
      }>
    }

    publishing.variants.mutate · Cancel, retry or complete destinations

    Cancels, retries or marks as published by hand (manual_complete, with an https permalink) up to 100 destinations, each on its own. A retry sends to the network again, so agents never run it.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.variants.mutate
    MCP toolpublishing_variants_mutate
    Scopepublishing.write
    Minimum roleMember
    Human confirmationYes
    DoorsAPI, Screens, Apps
    StatusAvailable

    Input

    {
      variantIds: string[]  // ≤ 100 items
      action: "cancel" | "retry" | "manual_complete"
      permalink?: string  // ≤ 2048
    }

    Output

    {
      results: Array<{
        variantId: string  // uuid
        ok: boolean
        error?: string
      }>
    }

    publishing.variants.mark_published · Mark as published

    Records a destination published by hand (a manual one, or a handoff of a connected account), with its https permalink and the time it went out when known. The assignee, Nömad on the post or an owner/admin.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.variants.mark_published
    MCP toolpublishing_variants_mark_published
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      postId: string  // uuid
      variantId: string  // uuid
      permalink?: string | null
      publishedAt?: string | null
    }

    Output

    {
      ok: true
    }

    publishing.posts.delete · Delete posts

    Removes up to 100 posts that never reached a network (drafts, ideas, scheduled, cancelled or failed destinations, nothing in flight). A post that went out once stays in the brand history, also after being taken down (publishing_post_published); take it off the network with publishing.remote.delete. One result per post; a refused one does not undo the others.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.posts.delete
    MCP toolpublishing_posts_delete
    Scopepublishing.write
    Minimum roleMember
    Human confirmationYes
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      postIds: string[]  // ≤ 100 items
    }

    Output

    {
      results: Array<{
        postId: string  // uuid
        ok: boolean
        error?: string
        newPostId?: string  // uuid
      }>
    }

    publishing.posts.duplicate · Duplicate posts

    Copies up to 50 posts into new drafts (content, destinations and media; never dates, reviews or delivery), titled «… (copy)» in the caller language. One result per post with the new id.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.posts.duplicate
    MCP toolpublishing_posts_duplicate
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      postIds: string[]  // ≤ 50 items
    }

    Output

    {
      results: Array<{
        postId: string  // uuid
        ok: boolean
        error?: string
        newPostId?: string  // uuid
      }>
    }

    publishing.posts.start_work · Start a post

    Starts a post: adds the free «Post» work with its publication task and answers with the relative path to open (carrying the calendar date). With ideaPostId the idea becomes that post. Brands outside posts as works get the direct composer path.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.posts.start_work
    MCP toolpublishing_posts_start_work
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      at?: string  // date-time
      tz?: string  // ≤ 64
      ideaPostId?: string  // uuid
      attemptId?: string  // uuid
    }

    Output

    {
      href: string
    }

    publishing.planned.bind · Bind planned destinations

    Binds every planned destination of a network in the brand to one of its connected accounts («¿Con qué cuenta publicamos?»). Idempotent. Returns how many were bound, scheduled, past their date or skipped.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.planned.bind
    MCP toolpublishing_planned_bind
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      network: string  // ≤ 60
      connectionId: string  // uuid
    }

    Output

    {
      bound: integer  // -9007199254740991–9007199254740991
      scheduled: integer  // -9007199254740991–9007199254740991
      datePassed: integer  // -9007199254740991–9007199254740991
      skipped: integer  // -9007199254740991–9007199254740991
    }

    publishing.remote.delete · Delete from the network

    Deletes one published destination from its network, then records it. Owners and admins delete any destination, members the posts they own. Only a confirmed deletion (or one the network no longer has) is written. Never an agent's to do.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.remote.delete
    MCP toolpublishing_remote_delete
    Scopepublishing.write
    Minimum roleMember
    Human confirmationYes
    DoorsAPI, Screens, Apps
    StatusAvailable

    Input

    {
      variantId: string  // uuid
    }

    Output

    {
      variantId: string  // uuid
      postId: string  // uuid
      outcome: "deleted" | "already_gone" | "already_deleted"
      deletedAt: string | null
    }

    publishing.media.prepare · Prepare files for publishing

    Reads attached Library files the way delivery will (type, size, dimensions, duration) and, unless start is false, starts the automatic check for files that have none. Returns each file with its state: ready, running or failed with the reason.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.media.prepare
    MCP toolpublishing_media_prepare
    Scopepublishing.write
    Minimum roleViewer
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      fileIds: string[]  // ≤ 50 items
      start?: boolean
      retry?: boolean
    }

    Output

    {
      media: Record<string, unknown>[]
    }

    publishing.media.start_job · Start a media job

    Starts the check of one file or, with a recipe (width, height, fit, format, fps, maxBytes), a derived version for a network. The original is never overwritten. Returns the queued job.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.media.start_job
    MCP toolpublishing_media_start_job
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      fileId: string  // uuid
      recipe?: {
        width?: integer  // -9007199254740991–9007199254740991
        height?: integer  // -9007199254740991–9007199254740991
        fit?: "cover" | "contain"
        format?: "jpeg" | "mp4"
        fps?: integer  // -9007199254740991–9007199254740991
        maxBytes?: integer  // -9007199254740991–9007199254740991
      }
    }

    Output

    {
      job: Record<string, unknown>
    }

    publishing.media.accept_derivative · Accept a derived file

    Accepts the derived version of a file (made by publishing.media.start_job) for publishing. Acceptance is explicit and brand-scoped; the original stays as it was. Returns the file as a post uses it.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.media.accept_derivative
    MCP toolpublishing_media_accept_derivative
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      derivativeId: string  // uuid
    }

    Output

    {
      media: Record<string, unknown>
    }

    publishing.settings.configure_policy · Configure the approval policy

    Saves the brand approval policy (none, internal, internal and client), its rules, reviewers and time zone, fenced by version. Owners and admins only. Returns the policy as stored.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.settings.configure_policy
    MCP toolpublishing_settings_configure_policy
    Scopepublishing.write
    Minimum roleMember
    Human confirmationYes
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      policy: Record<string, unknown>  // `PublishingPolicy` as settings › Publicación edits it.
    }

    Output

    {
      policy: Record<string, unknown>
    }

    publishing.settings.configure_queue · Configure an account queue

    Saves the weekly slots, time zone and ambiguous-time rule of one connected account queue, fenced by version. Owners and admins only. Returns the queue as stored.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.settings.configure_queue
    MCP toolpublishing_settings_configure_queue
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      queue: Record<string, unknown>  // `PublishingQueue`: connectionId, timezone, slots, version, ambiguousTime.
    }

    Output

    {
      queue: Record<string, unknown>
    }

    publishing.settings.pause · Pause or resume publishing

    Pauses or resumes publishing for the whole brand or, with connectionId, one account. While paused nothing goes out. Owners and admins only. Returns the policy and queues as they stand.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.settings.pause
    MCP toolpublishing_settings_pause
    Scopepublishing.write
    Minimum roleMember
    Human confirmationYes
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      paused: boolean
      connectionId?: string  // uuid
    }

    Output

    {
      policy: Record<string, unknown>
      queues: Record<string, unknown>[]
    }

    publishing.queue.reorder · Reorder a queue

    Applies a new order to one account queue exactly as previewed (expectedPlan); if anything moved since, nothing changes and it fails with publishing_conflict. Owners and admins only.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.queue.reorder
    MCP toolpublishing_queue_reorder
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      connectionId: string  // uuid
      variantIds: string[]  // ≤ 100 items
      expectedPlan: Record<string, unknown>[]  // ≤ 100 items
    }

    Output

    {
      ok: true
    }

    publishing.external_reviews.issue_links · Issue client review links

    Issues one review link, valid seven days, for each configured client email that has not decided yet on a review request (policy internal and client). Only the token hash is stored. Owners and admins only.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.external_reviews.issue_links
    MCP toolpublishing_external_reviews_issue_links
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      requestId: string  // uuid
    }

    Output

    {
      links: Array<{
        email: string
        url: string
        expiresAt: string
      }>
    }

    publishing.external_reviews.revoke_link · Revoke a client review link

    Revokes the review link of one client email on a review request; the link stops working at once. Owners and admins only.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.external_reviews.revoke_link
    MCP toolpublishing_external_reviews_revoke_link
    Scopepublishing.write
    Minimum roleMember
    Human confirmationYes
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      requestId: string  // uuid
      email: string  // email · ≤ 254
    }

    Output

    {
      ok: true
    }

    publishing.history.rerun_import · Re-import post history

    Re-imports the last 90 days of posts of an Instagram, Facebook Page or Threads connection. Answers whether the run was queued or is already running.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.history.rerun_import
    MCP toolpublishing_history_rerun_import
    Scopepublishing.write
    Minimum roleAdmin
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      connectionId: string  // uuid
    }

    Output

    {
      status: "queued" | "running"
      runId: string | null
    }

    publishing.calendar.reschedule · Reschedule from the calendar

    Moves destinations of one post to a new instant, exactly as the composer would. When the move costs an approval under a review policy, it asks for it again. Returns each destination status and whether approval was requested.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.calendar.reschedule
    MCP toolpublishing_calendar_reschedule
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      variantIds: string[]  // ≤ 50 items
      scheduledAt: string  // date-time
      timeZone: string  // ≤ 100
    }

    Output

    {
      variants: Array<{
        variantId: string  // uuid
        status: string
        scheduledAt: string | null
      }>
      reviewRequested: boolean
      needsApproval: boolean
    }

    publishing.calendar.swap · Swap two schedules

    Exchanges the times of two scheduled destinations (the Instagram grid drag). If one move fails, the ones already made are undone. Returns each destination status and whether approval was requested.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.calendar.swap
    MCP toolpublishing_calendar_swap
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      firstVariantId: string  // uuid
      secondVariantId: string  // uuid
    }

    Output

    {
      variants: Array<{
        variantId: string  // uuid
        status: string
        scheduledAt: string | null
      }>
      reviewRequested: boolean
      needsApproval: boolean
    }

    publishing.calendar.duplicate · Duplicate a post

    Creates a new draft with the same copy, media and destinations (accounts still connected) and no schedule, under the given title. Returns the new post id.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.calendar.duplicate
    MCP toolpublishing_calendar_duplicate
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      postId: string  // uuid
      title: string  // ≤ 500
    }

    Output

    {
      postId: string  // uuid
    }

    publishing.agency.accept · Accept a post from Nömad

    The brand approves every destination Nömad prepared on a post, with an optional note; they go out at their time. Only whoever decides Nömad posts for the brand. Returns the post approval state.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.agency.accept
    MCP toolpublishing_agency_accept
    Scopepublishing.write
    Minimum roleViewer
    Human confirmationYes
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      postId: string  // uuid
      note?: string  // ≤ 10000 · default ""
    }

    Output

    {
      state: string
    }

    publishing.agency.accept_with_changes · Accept with changes

    The brand saves its own edit of a post Nömad prepared and approves it in one step (recorded as approved with changes); schedule can move its time. Returns the approval state.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.agency.accept_with_changes
    MCP toolpublishing_agency_accept_with_changes
    Scopepublishing.write
    Minimum roleMember
    Human confirmationYes
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      draft: Record<string, unknown>  // The composer draft (`PublishingPostDraft`): id and expectedVersion to edit, title, baseText, tags, media and one variant per destination.
      schedule: {
        mode: "fixed" | "now"
        scheduledAt?: string  // date-time
        timezone: string  // ≤ 100
      }
      | null
      note?: string  // ≤ 10000 · default ""
    }

    Output

    {
      state: string
    }

    publishing.agency.request_changes · Request changes from Nömad

    The brand asks for changes on a post Nömad prepared, always saying what to change; Nömad's task opens again with it. Returns the approval state.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.agency.request_changes
    MCP toolpublishing_agency_request_changes
    Scopepublishing.write
    Minimum roleViewer
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      postId: string  // uuid
      note: string  // ≤ 10000
    }

    Output

    {
      state: string
    }

    publishing.agency.record_approval · Record an approval

    Nömad records what the client said off the app (who, through which channel, when): approved, or rejected with what to change. Nömad staff on the post only. Returns the approval state.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.agency.record_approval
    MCP toolpublishing_agency_record_approval
    Scopepublishing.write
    Minimum roleMember
    Human confirmationYes
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      postId: string  // uuid
      decision: "approved" | "rejected"
      channel: string  // ≤ 40
      approverName: string  // ≤ 200
      decidedAt: string  // date-time
      note: string  // ≤ 10000
    }

    Output

    {
      state: string
    }

    publishing.approval_links.create · Send for approval

    Creates an approval link to one post for one contact. By email Nömad sends it; for WhatsApp or to copy, the caller shares the returned url. Nömad on the post or an owner/admin. Fails with publishing_email_not_sent when the email could not go.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.approval_links.create
    MCP toolpublishing_approval_links_create
    Scopepublishing.write
    Minimum roleMember
    Human confirmationYes
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      postId: string  // uuid
      channel: "email" | "whatsapp" | "link"
      email?: string | null
      label?: string | null
    }

    Output

    {
      url: string
      expiresAt: string
      emailed: boolean
    }

    publishing.approval_links.revoke · Revoke an approval link

    Revokes one approval link of a post; it stops working at once. Nömad on the post or an owner/admin.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.approval_links.revoke
    MCP toolpublishing_approval_links_revoke
    Scopepublishing.write
    Minimum roleMember
    Human confirmationYes
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      postId: string  // uuid
      linkId: string  // uuid
    }

    Output

    {
      ok: true
    }

    publishing.writer.topics · Propose topics with Nödo

    Nödo proposes topics for a post from the editorial plan, briefing and what was published. Saves nothing. Spends brand AI budget; when it is off or spent, the ideas come without Nödo angles and usage says why.

    Consumes the brand AI budget.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.writer.topics
    MCP toolpublishing_writer_topics
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      taskId?: string | null
      postId?: string | null
      exclude?: string[]  // ≤ 30 items
      like?: {
        title: string  // ≤ 200
        angle: string | null
        source: string  // ≤ 40
        pillar: string | null
        date: string | null
      }
      | null
    }

    Output

    {
      result: Record<string, unknown>
    }

    publishing.writer.compose · Write with Nödo

    Nödo writes a draft for the chosen networks in the brand voice, from a prompt, topic, template, link, briefing or text. Saves nothing: the person picks and saves. Spends brand AI budget.

    Consumes the brand AI budget.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.writer.compose
    MCP toolpublishing_writer_compose
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      taskId?: string | null
      postId?: string | null
      prompt: string  // ≤ 2000
      topic?: {
        title: string  // ≤ 200
        angle: string | null
        source: string  // ≤ 40
        pillar: string | null
        date: string | null
      }
      | null
      template?: string | null
      goal?: string | null
      length: string  // ≤ 20
      cta: boolean
      source?: {
        kind: "link"
        url: string  // ≤ 2048
      }
      | {
        kind: "briefing"
      }
      | {
        kind: "text"
        text: string  // ≤ 20000
      }
      | null
      without?: string[]  // ≤ 20 items · default []
      connectionId: string | null
      targets: Array<{
        connectionId: string  // ≤ 80
        format: string  // ≤ 40
      }>  // ≤ 20 items
    }

    Output

    {
      result: Record<string, unknown>
    }

    publishing.writer.refine · Refine with Nödo

    Nödo rewrites a text (shorter, another tone, translated, with an instruction…) keeping the brand rules; kept lists rules the instruction asked to break. Saves nothing. Spends brand AI budget.

    Consumes the brand AI budget.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.writer.refine
    MCP toolpublishing_writer_refine
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      taskId?: string | null
      postId?: string | null
      text: string  // ≤ 10000
      action: string  // ≤ 40
      instruction?: string | null
      language?: string | null
      subject?: string | null
      connectionId: string | null
      targets: Array<{
        connectionId: string  // ≤ 80
        format: string  // ≤ 40
      }>  // ≤ 20 items
      hashtags: string[]  // ≤ 20 items
    }

    Output

    {
      result: Record<string, unknown>
    }

    publishing.writer.adapt · Adapt per network with Nödo

    Nödo adapts one text to each chosen network with its rules and the brand voice for that network. Saves nothing. Spends brand AI budget.

    Consumes the brand AI budget.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.writer.adapt
    MCP toolpublishing_writer_adapt
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      taskId?: string | null
      postId?: string | null
      text: string  // ≤ 10000
      targets: Array<{
        connectionId: string  // ≤ 80
        format: string  // ≤ 40
      }>  // ≤ 20 items
    }

    Output

    {
      result: Record<string, unknown>
    }

    publishing.writer.mark_assisted · Record Nödo assistance

    After a save, records on the post that Nödo helped write it, with the sources and networks it used. Answers whether it was recorded.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.writer.mark_assisted
    MCP toolpublishing_writer_mark_assisted
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      postId: string  // uuid
      sources: string[]  // ≤ 20 items
      networks: string[]  // ≤ 20 items
    }

    Output

    {
      recorded: boolean
    }

    publishing.editorial_plan.save_rhythm · Save the editorial rhythm

    Saves the weekly rhythm (slots per network and pillar) of an editorial-plan task, fenced by expectedRevision. Returns the board.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.editorial_plan.save_rhythm
    MCP toolpublishing_editorial_plan_save_rhythm
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      taskId: string  // uuid
      slots: unknown[]  // ≤ 42 items
      expectedRevision: integer  // 0–9007199254740991
    }

    Output

    {
      board: Record<string, unknown>
    }

    publishing.editorial_plan.save_month · Save the editorial month

    Saves the month plan (ideas per date) of an editorial-plan task, fenced by expectedRevision. Returns the board.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.editorial_plan.save_month
    MCP toolpublishing_editorial_plan_save_month
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      taskId: string  // uuid
      plan: unknown
      expectedRevision: integer  // 0–9007199254740991
    }

    Output

    {
      board: Record<string, unknown>
    }

    publishing.editorial_plan.improve · Improve the plan with Nödo

    Nödo replaces a default first rhythm and default ideas of an editorial-plan task with ones written for the brand. Spends brand AI budget. Returns the board.

    Consumes the brand AI budget.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.editorial_plan.improve
    MCP toolpublishing_editorial_plan_improve
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      taskId: string  // uuid
      locale?: string  // default "es"
    }

    Output

    {
      board: Record<string, unknown>
    }

    publishing.editorial_plan.propose_rebalance · Rebalance the month with Nödo

    Nödo proposes a more balanced month plan, shown as a diff, with the sources it read. Nothing is saved until the brand accepts it. Spends brand AI budget.

    Consumes the brand AI budget.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.editorial_plan.propose_rebalance
    MCP toolpublishing_editorial_plan_propose_rebalance
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      taskId: string  // uuid
      locale?: string  // default "es"
    }

    Output

    {
      plan: Record<string, unknown>
      sources: Record<string, unknown>[]
    }

    publishing.editorial_plan.approve · Approve the editorial plan

    Approves the rhythm or the month of an editorial-plan task from its board (or retries a failed step), fenced by expectedRevision. A brand person must be the work approver; Nömad staff approve on the brand behalf. Returns the board.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.editorial_plan.approve
    MCP toolpublishing_editorial_plan_approve
    Scopepublishing.write
    Minimum roleMember
    Human confirmationYes
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      taskId: string  // uuid
      part: "rhythm" | "month" | "retry"
      expectedRevision: integer  // 0–9007199254740991
    }

    Output

    {
      board: Record<string, unknown>
    }

    publishing.themes.update · Edit a theme

    Edits one theme of the brand theme bank (theme, description, key message, hook, category, funnel stage, network, content type, production notes). Fields left out keep their value; the edit is added to the theme history.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.themes.update
    MCP toolpublishing_themes_update
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      themeId: string  // uuid
      changes: {
        theme?: string  // ≤ 500
        description?: string | null
        key_message?: string | null
        hook_idea?: string | null
        category?: string  // ≤ 80
        target_stage?: string  // ≤ 80
        recommended_network?: string | null
        content_type?: string | null
        production_notes?: string | null
      }
    }

    Output

    {
      ok: true
      changed: string[]
    }

    publishing.themes.delete · Delete a theme

    Takes an active theme out of the brand theme bank for everyone. It is archived, so publishing.themes.restore puts it back.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.themes.delete
    MCP toolpublishing_themes_delete
    Scopepublishing.write
    Minimum roleAdmin
    Human confirmationYes
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      themeId: string  // uuid
    }

    Output

    {
      ok: true
    }

    publishing.themes.restore · Restore a theme

    Puts a deleted (archived) theme back in the brand theme bank. Fails with not_found when the theme is not deleted.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.themes.restore
    MCP toolpublishing_themes_restore
    Scopepublishing.write
    Minimum roleAdmin
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      themeId: string  // uuid
    }

    Output

    {
      ok: true
    }

    publishing.themes.create · Add a theme

    Adds a theme written by a person to the brand theme bank (category defaults to educational, stage to awareness). Returns the new theme row.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.themes.create
    MCP toolpublishing_themes_create
    Scopepublishing.write
    Minimum roleMember
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      theme: string  // ≤ 500
      description?: string  // ≤ 4000
      category?: string  // ≤ 80
      target_stage?: string  // ≤ 80
      key_message?: string  // ≤ 2000
      hook_idea?: string  // ≤ 2000
    }

    Output

    {
      theme: {
        id: string  // uuid
        theme: string
      }
    }

    publishing.themes.generate · Generate the theme bank

    Starts an AI generation of the brand theme bank in the background: full rebuilds it, append adds about 60 themes keeping the current ones. Returns the generation id; the bank fills in when it finishes.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.themes.generate
    MCP toolpublishing_themes_generate
    Scopepublishing.write
    Minimum roleAdmin
    Human confirmationYes
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      mode: "full" | "append"
    }

    Output

    {
      generationId: string  // uuid
    }

    publishing.themes.reset_status · Unblock the theme generation

    Marks the latest theme bank generation stuck in generating as failed, so a new one can start. Does nothing when none is running.

    FieldValue
    KindWrite
    HTTP methodPOST /api/v1/publishing.themes.reset_status
    MCP toolpublishing_themes_reset_status
    Scopepublishing.write
    Minimum roleAdmin
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {}

    Output

    {
      ok: true
      reset: boolean
    }

    publishing.posts.awaiting · Posts awaiting the brand

    What Nömad prepared and waits for the brand's approval, newest request first, leaving out posts whose work names another approver. total counts them all; savedTimeZone is the zone the person saved for the brand calendar, if any.

    FieldValue
    KindRead
    HTTP methodPOST /api/v1/publishing.posts.awaiting
    MCP toolpublishing_posts_awaiting
    Scopepublishing.read
    Minimum roleViewer
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      limit?: integer  // 1–20 · default 4
    }

    Output

    {
      items: Record<string, unknown>[]
      total: integer  // 0–9007199254740991
      savedTimeZone: string | null
    }

    publishing.editorial_plan.board · Read the editorial plan

    The board of an editorial-plan task: rhythm, month, whether the reader can edit or approve it and who approves it. Whoever can edit sees the first rhythm or month as a preview (revision 0) until the first change stores it.

    FieldValue
    KindRead
    HTTP methodPOST /api/v1/publishing.editorial_plan.board
    MCP toolpublishing_editorial_plan_board
    Scopepublishing.read
    Minimum roleViewer
    Human confirmationNo
    DoorsAPI, MCP, Screens, Apps, Nödo
    StatusAvailable

    Input

    {
      taskId: string  // uuid
      fallbackPillars?: string[]  // ≤ 6 items · default []
      preview?: boolean  // Staff previewing the brand as a client: edit controls are left out.
    }

    Output

    {
      board: {
        canEdit: boolean
        canApprove: boolean
        approverNames: string[]
      }
    }

    Updated on January 1, 1970

    PreviousConnectionsNextInbox

    In this section

    • Errors
    • Permissions and roles
    • Events and webhooks
    • Brand
    • Genome
    • Brand Kit
    • Library
    • Works
    Can't find what you need? Write to usWrite to usGo to the app
    © 2026 Nömad · Nömad documentationLinkedInInstagramThreadsFacebookTikTokYouTubeX
    Go to nomad.oooBack to top

    On this page

    • publishing.posts.list · List posts
    • publishing.posts.get · Get a post
    • publishing.posts.draft · Draft a post
    • publishing.posts.request_review · Request review
    • publishing.posts.schedule · Propose a publish time
    • publishing.accounts.list · Publishing accounts
    • publishing.formats.describe · Format rules
    • publishing.metrics.get · Post metrics
    • publishing.ideas.create · Save an idea
    • publishing.ideas.list · List ideas
    • publishing.mentions.suggest · Suggest mentions
    • publishing.networks.list · Networks and formats
    • publishing.posts.save · Save a post
    • publishing.variants.schedule · Schedule or publish now
    • publishing.reviews.request · Request approval
    • publishing.reviews.decide · Decide a review
    • publishing.comments.add · Comment on a post
    • publishing.posts.mutate · Cancel or retry posts
    • publishing.variants.mutate · Cancel, retry or complete destinations
    • publishing.variants.mark_published · Mark as published
    • publishing.posts.delete · Delete posts
    • publishing.posts.duplicate · Duplicate posts
    • publishing.posts.start_work · Start a post
    • publishing.planned.bind · Bind planned destinations
    • publishing.remote.delete · Delete from the network
    • publishing.media.prepare · Prepare files for publishing
    • publishing.media.start_job · Start a media job
    • publishing.media.accept_derivative · Accept a derived file
    • publishing.settings.configure_policy · Configure the approval policy
    • publishing.settings.configure_queue · Configure an account queue
    • publishing.settings.pause · Pause or resume publishing
    • publishing.queue.reorder · Reorder a queue
    • publishing.external_reviews.issue_links · Issue client review links
    • publishing.external_reviews.revoke_link · Revoke a client review link
    • publishing.history.rerun_import · Re-import post history
    • publishing.calendar.reschedule · Reschedule from the calendar
    • publishing.calendar.swap · Swap two schedules
    • publishing.calendar.duplicate · Duplicate a post
    • publishing.agency.accept · Accept a post from Nömad
    • publishing.agency.accept_with_changes · Accept with changes
    • publishing.agency.request_changes · Request changes from Nömad
    • publishing.agency.record_approval · Record an approval
    • publishing.approval_links.create · Send for approval
    • publishing.approval_links.revoke · Revoke an approval link
    • publishing.writer.topics · Propose topics with Nödo
    • publishing.writer.compose · Write with Nödo
    • publishing.writer.refine · Refine with Nödo
    • publishing.writer.adapt · Adapt per network with Nödo
    • publishing.writer.mark_assisted · Record Nödo assistance
    • publishing.editorial_plan.save_rhythm · Save the editorial rhythm
    • publishing.editorial_plan.save_month · Save the editorial month
    • publishing.editorial_plan.improve · Improve the plan with Nödo
    • publishing.editorial_plan.propose_rebalance · Rebalance the month with Nödo
    • publishing.editorial_plan.approve · Approve the editorial plan
    • publishing.themes.update · Edit a theme
    • publishing.themes.delete · Delete a theme
    • publishing.themes.restore · Restore a theme
    • publishing.themes.create · Add a theme
    • publishing.themes.generate · Generate the theme bank
    • publishing.themes.reset_status · Unblock the theme generation
    • publishing.posts.awaiting · Posts awaiting the brand
    • publishing.editorial_plan.board · Read the editorial plan