Skip to content
Yamuno
Browse

API Examples

cURL Examples

Create a New Page

curl -X POST "https://your-site.atlassian.net/wiki/apps/your-app-id/your-env-id/webtrigger" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "spaceId": "98765432",
    "parentId": "123456789",
    "pageTitle": "Getting Started",
    "content": "# Getting Started\n\nWelcome to our documentation!\n\n## Installation\n\n```bash\nnpm install our-package\n```",
    "overwrite": false
  }'

Update Existing Page

curl -X POST "https://your-site.atlassian.net/wiki/apps/your-app-id/your-env-id/webtrigger" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "spaceId": "98765432",
    "parentId": "123456789",
    "pageTitle": "API Reference",
    "content": "# API Reference\n\nUpdated content here...",
    "overwrite": true
  }'

Node.js / JavaScript

Using Axios

const axios = require('axios');

async function importToConfluence() {
  const endpoint = process.env.CONFLUENCE_API_ENDPOINT;
  const token = process.env.CONFLUENCE_API_TOKEN;

  try {
    const response = await axios.post(endpoint, {
      spaceId: '98765432',
      parentId: '123456789',
      pageTitle: 'Automated Documentation',
      content: '# Automated Update\n\nThis page was updated automatically.',
      overwrite: true
    }, {
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      }
    });

    console.log('Success:', response.data);
  } catch (error) {
    console.error('Error:', error.response?.data || error.message);
  }
}

importToConfluence();

Using Fetch

async function importToConfluence() {
  const endpoint = process.env.CONFLUENCE_API_ENDPOINT;
  const token = process.env.CONFLUENCE_API_TOKEN;

  try {
    const response = await fetch(endpoint, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        spaceId: '98765432',
        parentId: '123456789',
        pageTitle: 'Automated Documentation',
        content: '# Automated Update\n\nThis page was updated automatically.',
        overwrite: true
      })
    });

    const data = await response.json();

    if (response.ok) {
      console.log('Success:', data);
    } else {
      console.error('Error:', data);
    }
  } catch (error) {
    console.error('Network error:', error.message);
  }
}

importToConfluence();

Reading from File

const fs = require('fs');
const axios = require('axios');

async function importMarkdownFile(filePath, pageTitle) {
  const endpoint = process.env.CONFLUENCE_API_ENDPOINT;
  const token = process.env.CONFLUENCE_API_TOKEN;

  // Read markdown file
  const content = fs.readFileSync(filePath, 'utf8');

  try {
    const response = await axios.post(endpoint, {
      spaceId: '98765432',
      parentId: '123456789',
      pageTitle: pageTitle,
      content: content,
      overwrite: true
    }, {
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      }
    });

    console.log(`✓ Successfully imported ${filePath}`);
  } catch (error) {
    console.error(`✗ Failed to import ${filePath}:`, error.response?.data || error.message);
  }
}

// Usage
importMarkdownFile('./docs/README.md', 'Project README');

Python

Basic Example

import requests
import os

def import_to_confluence(title, content, overwrite=False):
    endpoint = os.environ['CONFLUENCE_API_ENDPOINT']
    token = os.environ['CONFLUENCE_API_TOKEN']

    headers = {
        'Authorization': f'Bearer {token}',
        'Content-Type': 'application/json'
    }

    payload = {
        'spaceId': '98765432',
        'parentId': '123456789',
        'pageTitle': title,
        'content': content,
        'overwrite': overwrite
    }

    response = requests.post(endpoint, json=payload, headers=headers)

    if response.status_code in [200, 201]:
        print(f'✓ Success: {response.json()["body"]}')
    else:
        print(f'✗ Error: {response.json()["body"]}')

    return response

# Usage
with open('README.md', 'r') as f:
    markdown_content = f.read()

import_to_confluence('Project README', markdown_content, overwrite=True)

Batch Import

import requests
import os
from pathlib import Path

def import_multiple_files(files_dict):
    """
    Import multiple markdown files
    files_dict: {'Page Title': 'path/to/file.md'}
    """
    endpoint = os.environ['CONFLUENCE_API_ENDPOINT']
    token = os.environ['CONFLUENCE_API_TOKEN']

    headers = {
        'Authorization': f'Bearer {token}',
        'Content-Type': 'application/json'
    }

    results = {'success': [], 'failed': []}

    for title, filepath in files_dict.items():
        try:
            with open(filepath, 'r', encoding='utf-8') as f:
                content = f.read()

            payload = {
                'spaceId': '98765432',
                'parentId': '123456789',
                'pageTitle': title,
                'content': content,
                'overwrite': True
            }

            response = requests.post(endpoint, json=payload, headers=headers)

            if response.status_code in [200, 201]:
                results['success'].append(title)
                print(f'✓ {title}')
            else:
                results['failed'].append((title, response.json()['body']))
                print(f'✗ {title}: {response.json()["body"]}')

        except Exception as e:
            results['failed'].append((title, str(e)))
            print(f'✗ {title}: {str(e)}')

    print(f'\nCompleted: {len(results["success"])} success, {len(results["failed"])} failed')
    return results

# Usage
files = {
    'Getting Started': 'docs/getting-started.md',
    'API Reference': 'docs/api-reference.md',
    'Examples': 'docs/examples.md'
}

import_multiple_files(files)

GitHub Actions

Ready-made Action

confluence-markdown-sync is an open source GitHub Action that publishes the Markdown files in a folder through this API, one page per file under a single parent page:

- uses: actions/checkout@v4
- uses: Yamuno-Software/confluence-markdown-sync@v1
  with:
    endpoint: ${{ secrets.CONFLUENCE_API_ENDPOINT }}
    token: ${{ secrets.CONFLUENCE_API_TOKEN }}
    space-id: "98765432"
    parent-id: "123456789"
    path: docs

Store the endpoint and token as repository secrets. See the Action's README for all inputs. The examples below show how to call the API directly if you want full control.

Update Docs on Push

name: Update Confluence Docs

on:
  push:
    branches: [main]
    paths:
      - 'docs/**'

jobs:
  update-confluence:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Import to Confluence
        run: |
          curl -X POST "${{ secrets.CONFLUENCE_API_ENDPOINT }}" \
            -H "Authorization: Bearer ${{ secrets.CONFLUENCE_API_TOKEN }}" \
            -H "Content-Type: application/json" \
            -d @- <<EOF
          {
            "spaceId": "98765432",
            "parentId": "123456789",
            "pageTitle": "API Documentation",
            "content": $(cat docs/api.md | jq -Rs .),
            "overwrite": true
          }
          EOF

Multiple Files

name: Sync Documentation

on:
  push:
    branches: [main]
    paths:
      - 'docs/**'

jobs:
  sync-docs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Import README
        run: |
          CONTENT=$(cat README.md | jq -Rs .)
          curl -X POST "${{ secrets.CONFLUENCE_API_ENDPOINT }}" \
            -H "Authorization: Bearer ${{ secrets.CONFLUENCE_API_TOKEN }}" \
            -H "Content-Type: application/json" \
            -d "{\"spaceId\":\"98765432\",\"parentId\":\"123456789\",\"pageTitle\":\"README\",\"content\":$CONTENT,\"overwrite\":true}"

      - name: Import API Docs
        run: |
          CONTENT=$(cat docs/api.md | jq -Rs .)
          curl -X POST "${{ secrets.CONFLUENCE_API_ENDPOINT }}" \
            -H "Authorization: Bearer ${{ secrets.CONFLUENCE_API_TOKEN }}" \
            -H "Content-Type: application/json" \
            -d "{\"spaceId\":\"98765432\",\"parentId\":\"123456789\",\"pageTitle\":\"API Reference\",\"content\":$CONTENT,\"overwrite\":true}"

GitLab CI/CD

stages:
  - deploy-docs

deploy-confluence:
  stage: deploy-docs
  only:
    - main
  script:
    - |
      curl -X POST "$CONFLUENCE_API_ENDPOINT" \
        -H "Authorization: Bearer $CONFLUENCE_API_TOKEN" \
        -H "Content-Type: application/json" \
        -d "{
          \"spaceId\": \"98765432\",
          \"parentId\": \"123456789\",
          \"pageTitle\": \"API Documentation\",
          \"content\": $(cat docs/api.md | jq -Rs .),
          \"overwrite\": true
        }"

Go

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "os"
)

type ConfluenceRequest struct {
    SpaceID   string `json:"spaceId"`
    ParentID  string `json:"parentId"`
    PageTitle string `json:"pageTitle"`
    Content   string `json:"content"`
    Overwrite bool   `json:"overwrite"`
}

func importToConfluence(title, content string, overwrite bool) error {
    endpoint := os.Getenv("CONFLUENCE_API_ENDPOINT")
    token := os.Getenv("CONFLUENCE_API_TOKEN")

    reqBody := ConfluenceRequest{
        SpaceID:   "98765432",
        ParentID:  "123456789",
        PageTitle: title,
        Content:   content,
        Overwrite: overwrite,
    }

    jsonData, err := json.Marshal(reqBody)
    if err != nil {
        return err
    }

    req, err := http.NewRequest("POST", endpoint, bytes.NewBuffer(jsonData))
    if err != nil {
        return err
    }

    req.Header.Set("Authorization", "Bearer "+token)
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    body, _ := ioutil.ReadAll(resp.Body)

    if resp.StatusCode == 200 || resp.StatusCode == 201 {
        fmt.Printf("✓ Success: %s\n", string(body))
    } else {
        fmt.Printf("✗ Error: %s\n", string(body))
    }

    return nil
}

func main() {
    content, err := ioutil.ReadFile("README.md")
    if err != nil {
        fmt.Println("Error reading file:", err)
        return
    }

    err = importToConfluence("Project README", string(content), true)
    if err != nil {
        fmt.Println("Error:", err)
    }
}

Guides for Markdown Importer for Confluence Cloud

Stuck on something this page does not cover? Ask the developers.