BIM 360/ACC Sync

Download models from BIM 360/ACC and process locally.

Workflow Overview

BIM 360 / ACC Cloud
Hub
Project
Folder
Item
Version
Authentication
3-Legged OAuth
raps auth login
RAPS Operations
List/Navigate
Download
Get Metadata
Get Versions
Local Processing
Local Files
Translate
Extract Data

CLI Approach

Step 1: Authenticate

# Login with 3-legged OAuth (opens browser)
raps auth login

# Or use existing refresh token
raps auth refresh

Step 2: Navigate Project Hierarchy

# List all hubs (accounts)
raps hub list

# Save hub ID
HUB_ID="b.your-hub-id"

# List projects in hub
raps project list "$HUB_ID"

# Save project ID
PROJECT_ID="b.your-project-id"

# List top-level folders
raps folder list "$PROJECT_ID" --top

# List contents of specific folder
FOLDER_ID="urn:adsk.wipprod:fs.folder:abc123"
raps folder list "$PROJECT_ID" "$FOLDER_ID"

Step 3: Download Files

# List items in folder
raps folder list "$PROJECT_ID" "$FOLDER_ID" --output json > items.json

# Download specific item
ITEM_ID=$(jq -r '.[0].id' items.json)
raps item download "$PROJECT_ID" "$ITEM_ID" --output ./downloads/

# Download all items in folder
jq -r '.[].id' items.json | while read item_id; do
  raps item download "$PROJECT_ID" "$item_id" --output ./downloads/
done

Step 4: Get Version History

# List all versions of an item
raps item versions "$PROJECT_ID" "$ITEM_ID" --output json > versions.json

# Download specific version
VERSION_ID=$(jq -r '.[0].id' versions.json)
raps item download "$PROJECT_ID" "$ITEM_ID" --version "$VERSION_ID" --output ./downloads/

CI/CD Pipeline

# .github/workflows/acc-sync.yml
name: ACC Model Sync

on:
  schedule:
    - cron: '0 6 * * *'  # Daily at 6 AM
  workflow_dispatch:

env:
  HUB_ID: ${{ secrets.ACC_HUB_ID }}
  PROJECT_ID: ${{ secrets.ACC_PROJECT_ID }}
  FOLDER_ID: ${{ secrets.ACC_MODELS_FOLDER_ID }}

jobs:
  sync-models:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install RAPS
        run: cargo install raps

      - name: Authenticate with ACC
        env:
          APS_CLIENT_ID: ${{ secrets.APS_CLIENT_ID }}
          APS_CLIENT_SECRET: ${{ secrets.APS_CLIENT_SECRET }}
          APS_REFRESH_TOKEN: ${{ secrets.APS_REFRESH_TOKEN }}
        run: |
          raps auth refresh

      - name: Sync models from ACC
        env:
          APS_CLIENT_ID: ${{ secrets.APS_CLIENT_ID }}
          APS_CLIENT_SECRET: ${{ secrets.APS_CLIENT_SECRET }}
        run: |
          mkdir -p ./synced-models

          # List and download all Revit models
          raps folder list "$PROJECT_ID" "$FOLDER_ID" --output json | \
            jq -r '.[] | select(.name | endswith(".rvt")) | .id' | \
            while read item_id; do
              raps item download "$PROJECT_ID" "$item_id" --output ./synced-models/
            done

      - name: Upload to OSS for processing
        env:
          APS_CLIENT_ID: ${{ secrets.APS_CLIENT_ID }}
          APS_CLIENT_SECRET: ${{ secrets.APS_CLIENT_SECRET }}
        run: |
          BUCKET="acc-synced-$(date +%Y%m%d)"
          raps bucket create --key "$BUCKET" --policy transient --region US 2>/dev/null || true

          for model in ./synced-models/*.rvt; do
            [ -f "$model" ] || continue

            key=$(basename "$model")
            raps object upload "$BUCKET" "$model"

            URN=$(raps object urn "$BUCKET" "$key" --output plain)
            raps translate start "$URN" --format svf2
          done

      - name: Generate sync report
        run: |
          echo "# ACC Sync Report" > sync-report.md
          echo "Date: $(date)" >> sync-report.md
          echo "" >> sync-report.md
          echo "## Synced Files" >> sync-report.md
          ls -la ./synced-models/ >> sync-report.md

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: sync-report
          path: |
            sync-report.md
            ./synced-models/

Pipeline Flow

Schedule/Manual
Daily 6 AM
Authentication
Refresh Token
ACC Sync
List Folder
Download Models
OSS Processing
Upload to Bucket
Translate SVF2
Output
sync-report.md
synced-models/

MCP Integration

User: "Download the latest architectural model from the Main Street project in ACC"
User
AI Assistant
RAPS MCP
ACC Cloud
Download Main Street model
aps_hub_list()
Get hubs
aps_project_list()
Get projects
aps_folder_list()
Get contents
aps_item_download()
Download file
Download complete

AI Response:

Downloaded ‘MainStreet-Architectural-v42.rvt’ (156 MB)

  • Last modified: Feb 14, 2024 by John Smith
  • Version: 42
  • Saved to: ./downloads/MainStreet-Architectural-v42.rvt

List Recent Changes

User: "Show me what models changed in the Main Street project this week"

AI Response:

Files modified in Main Street project (Feb 12-16, 2024):

FileModifiedByVersion
Architectural.rvtFeb 14John Smithv42
MEP.rvtFeb 13Jane Doev28
Structural.rvtFeb 12Bob Wilsonv31

Would you like me to download any of these?

Sync and Process

User: "Sync all the Revit models from the Design folder and translate them"

AI Response:

Syncing 5 models from Design folder…

FileSizeStatus
Building-A.rvt124 MBDownloaded, translating…
Building-B.rvt98 MBDownloaded, translating…
Site.rvt45 MBDownloaded, translated
Landscape.rvt23 MBDownloaded, translated
Parking.rvt67 MBDownloaded, translating…

All files synced. 3 translations in progress, 2 complete.


Common Patterns

Incremental Sync

# Track last sync time
LAST_SYNC=$(cat .last-sync 2>/dev/null || echo "1970-01-01")

# Get items modified since last sync
raps folder list "$PROJECT_ID" "$FOLDER_ID" --output json | \
  jq --arg since "$LAST_SYNC" '[.[] | select(.lastModified > $since)]' | \
  jq -r '.[].id' | while read item_id; do
    raps item download "$PROJECT_ID" "$item_id" --output ./synced/
  done

# Update last sync time
date -Iseconds > .last-sync

Mirror Folder Structure

# Recursively sync folder structure
sync_folder() {
  local project_id=$1
  local folder_id=$2
  local local_path=$3

  mkdir -p "$local_path"

  raps folder list "$project_id" "$folder_id" --output json | while read -r item; do
    type=$(echo "$item" | jq -r '.type')
    name=$(echo "$item" | jq -r '.name')
    id=$(echo "$item" | jq -r '.id')

    if [ "$type" = "folders" ]; then
      sync_folder "$project_id" "$id" "$local_path/$name"
    else
      raps item download "$project_id" "$id" --output "$local_path/"
    fi
  done
}

sync_folder "$PROJECT_ID" "$FOLDER_ID" "./local-mirror"