Skip to content

Workflows

One sequence covers most integrations: pick a project, generate, poll, then publish.

01Article, then social

Article generate costs 1.5 credits. Social generate costs 0.6 per platform. Publish is free. Projects are created in the app.

const BASE = 'https://www.brainpercent.app/api/v1';
const headers = {
  Authorization: `Bearer ${API_KEY}`,
  'Content-Type': 'application/json',
};

async function poll(url, done) {
  for (;;) {
    const res = await fetch(url, { headers });
    const { data } = await res.json();
    if (data.status === 'failed') throw new Error('failed');
    if (done(data)) return data;
    await new Promise((r) => setTimeout(r, 15000));
  }
}

async function run(topic, platforms) {
  const projects = await fetch(`${BASE}/projects?limit=1`, { headers }).then((r) => r.json());
  const projectId = projects.data[0]?.id;
  if (!projectId) throw new Error('Create a project in the app first');

  const gen = await fetch(`${BASE}/articles/generate`, {
    method: 'POST',
    headers,
    body: JSON.stringify({ topic, project_id: projectId, word_count: 1200 }),
  }).then((r) => r.json());

  const article = await poll(`${BASE}${gen.data.poll_url}`, (d) => d.is_complete);
  const articleRes = await fetch(`${BASE}/articles/${article.article_id || gen.data.article_id}`, { headers });
  const { data: full } = await articleRes.json();

  const social = await fetch(`${BASE}/social/generate`, {
    method: 'POST',
    headers,
    body: JSON.stringify({
      source_url: full.canonical_url || full.url,
      platforms,
      source_type: 'blog',
      project_id: projectId,
    }),
  }).then((r) => r.json());

  return poll(`${BASE}${social.data.poll_url}`, (d) => d.status === 'ready' || d.status === 'completed');
}

02URL only

Skip the article. POST /social/generate accepts any public URL. Poll the content id, then POST /social/publish once a channel is connected in the app.

03Without HTTP

Claude on MCP already runs this sequence. Open the Claude & MCP page.