npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vocareum-publisher

v1.3.7

Published

Publish assignment content from GitHub to Vocareum

Readme

Vocareum Publisher

Push assignment content from GitHub to Vocareum.

A CLI tool and GitHub Action that enables instructors to maintain assignment content in Git with full version control while seamlessly syncing to Vocareum.

Released components (the CLI and the VS Code extension are versioned independently — see the CHANGELOG, npm, and the Releases page for current versions):

Video Walkthrough - Watch a quick demo of vocgit in action.

Features

  • Git-First Workflow: GitHub is the source of truth for all assignment content
  • CLI Tool: Local development and push via command line
  • GitHub Action: Automated CI/CD push on git push
  • Change Detection: Only uploads changed content (efficient)
  • Template-Based Creation: Create new assignments from templates
  • Validation: Verify configuration before pushing
  • Forward-Compatible Settings: Unrecognized Vocareum settings fields are preserved under _unknown_settings in vocareum.yaml and passed back through on push, so new platform features never silently drop out of your config

Installation

npm install -g vocareum-publisher

Quick Start

1. Initialize a Course Repository

mkdir my-course && cd my-course
git init
vocgit init

2. Create an Assignment

vocgit new lab1-intro
# Follow interactive prompts

3. Add Content

Add your files to the generated directory structure:

lab1-intro/
├── part1/
│   ├── startercode/   # Student-visible starter code
│   ├── scripts/       # Grading scripts
│   ├── docs/          # Documentation
│   ├── data/          # Datasets
│   └── private/       # Private files

vocgit new scaffolds one part (part1) with default directories: startercode, scripts, docs, data, and private. If needed, add lib and asnlib manually and include them in parts[].directories.

4. Validate and Push

vocgit validate
vocgit push

5. Commit and Push

git add .
git commit -m "Add Lab 1"
git push

Configuration

All configuration is stored in vocareum.yaml:

version: "1.0"

vocareum:
  org_id: "12345"
  course_id: "67890"
  templates:                        # Named templates for creating new assignments
    - id: "99999"
      name: "Standard Lab"
      course_id: "67890"            # Same course
    - id: "88888"
      name: "Cloud Lab"
      course_id: "11111"            # Template in different course
    - id: "77777"
      name: "Timed Exam"
      course_id: "67890"
  excluded_assignments:       # Assignment IDs to hide from orphan detection
    - "111222"
    - "333444"
  course_settings:            # Optional course metadata sync
    name: "Intro to ML"
    description: "Spring section"

assignments:
  - assignment_id: "11111"
    name: "Lab 1: Introduction"
    path: "lab1-intro"
    sync_settings: true              # Optional override; defaults to publish_options.sync_settings
    settings:                       # Optional assignment settings
      nosubmit: false
      publish: true
      publish_grades: false
      auto_submit: false
      grading_on_submit: true
      exam_mode: "TIMED"            # NO_EXAM, SCHEDULED, TIMED, TIMED_UNRESTRICTED
      exam_duration: 120
      num_attempts: 3
      grading_visibility: "ALL"     # ALL or ASSIGNED
      _observed_settings:           # Pull-only API fields; vocgit does not push these
        description: "Introduction to the course"
    parts:
      - part_id: "22222"
        path: "part1"
        name: "Part 1: Setup"
        sync_settings: true          # Optional part-level override
        settings:                   # Optional part settings
          submission_filters:
            include: ["*.py"]
            exclude: ["*.pyc"]
          session_length: "60"      # minutes
          late_penalty_percent: 10  # Accepted by API; may not echo on read
          late_penalty_percent_rule: "max score"
          deadlinedate: "2025-03-15T23:59:00Z"
          number_of_submissions: 5
          lab_interface:
            panels: ["Console"]
            controls: ["Reset"]
  - assignment_id: null
    name: "Lab 2: Classification"
    assignment_name_for_lookup: "Lab 2: Classification"  # Optional name-based ID discovery
    path: "lab2-classification"
    parts:
      - part_id: null
        path: "part1"
        name: "Part 1: Implementation"
        settings:
          cloud_labs: true
          session_length: "60"
          labtype: "JupyterLab"
          endlab: true

publish_options:
  on_missing_id: "skip"
  auto_commit: false
  sync_settings: true                # Set false to sync files only, not settings
  sync_deletes: false

publish_history:
  - timestamp: "2026-02-12T22:30:00Z"
    commit_sha: "abc123def456"
    published_by: "github-actions"
    status: "failed"   # success | failed
    content_state:
      "lab1-intro/part1/startercode": "9a7f..."
    failed:
      - type: "file"
        id: "22222/startercode/main.py"
        error: "Timed out after 30000ms waiting for part update (txn=123)"

Understanding Settings Sync

vocgit keeps assignment and part settings in sync between vocareum.yaml and Vocareum. The fields you set under settings: are pushed on vocgit push, and vocgit pull detects when Vocareum's values have drifted from yours.

Because Vocareum's API treats fields inconsistently — some are writable, some are read-only, some it accepts but never reports back — vocgit sorts every settings field into one of a few groups. After a pull, you may notice new keys appear in your YAML. These are expected and safe to leave alone:

  • Top-level settings (e.g. nosubmit, session_length, submission_filters) — fields vocgit both reads and writes. Edit these to change behavior on Vocareum.
  • _observed_settings — fields Vocareum reports on read but does not accept on write (or that only apply at create time). vocgit records them so your config reflects the real server state, but it never pushes them. Informational only.
  • _unknown_settings — fields vocgit doesn't recognize yet (typically new Vocareum features). vocgit preserves them verbatim and passes them back through unchanged on the next push, so nothing is silently lost. When these appear, vocgit prints an end-of-run notice asking you to file an issue so the field can be promoted to a supported setting.

"Accepted but not confirmed" fields. Some writable fields (e.g. exam_mode, exam_duration, deadlinedate, late_penalty_percent) are accepted by the API on write but are not echoed back on read. vocgit writes them and trusts the success response — it just can't read them back to confirm the value applied, so it won't report drift on them.

Opting out of settings sync

Set sync_settings: false to sync files only and leave Vocareum's settings untouched. This is useful when settings are managed in the Vocareum UI and you only want vocgit to push content.

Precedence (most specific wins): partassignmentpublish_options.sync_settings → defaults to true.

publish_options:
  sync_settings: false          # Global: don't sync any settings
assignments:
  - name: "Lab 1"
    sync_settings: true         # ...except this assignment
    parts:
      - path: "part1"
        sync_settings: false    # ...but not this part

When settings sync is disabled for an assignment or part, vocgit skips both pushing its settings and reporting settings drift for it on pull. The settings stay in vocareum.yaml — they're just ignored until you re-enable sync.

CLI Commands

| Command | Description | |---------|-------------| | vocgit init | Initialize a new course repository | | vocgit new <path> | Create new assignment structure | | vocgit validate | Validate configuration and structure | | vocgit fix | Interactively fix validation issues | | vocgit pull | Import or exclude orphaned assignments from Vocareum | | vocgit status | Show current local sync status (default command) | | vocgit push | Push content to Vocareum |

vocgit                  # Same as: vocgit status
vocgit status --verbose # Include per-assignment details
vocgit status --json    # Machine-readable content sync status (for tooling)

Workspace Root (--root)

Assignment and part paths in vocareum.yaml resolve against the workspace root. By default this is the current directory, and that only works when the config file sits directly inside it (the normal case — repo root, GitHub Action, VS Code extension).

If you run vocgit from somewhere else, or keep the config in a subdirectory, you must say where the workspace root is — guessing it can corrupt sync state:

vocgit push --config ../course-repo/vocareum.yaml --root ../course-repo
vocgit status --config configs/vocareum.yaml --root .   # nested config, cwd-relative paths

Without --root in those situations the command fails with an explanation rather than hashing the wrong directories. vocgit also refuses to read, upload, or delete anything outside the workspace root, including via symlinks.

Push Options

vocgit push --dry-run           # Preview changes
vocgit push --assignment lab1   # Push specific assignment
vocgit push --force-all         # Re-upload everything
vocgit push --sync-deletes      # Delete files not in Git (experimental)
vocgit push --non-interactive   # Skip confirmation prompt
vocgit push --verbose           # Detailed logging

Pull Command

The pull command helps you manage assignment sync issues:

  1. Orphaned assignments - exist in Vocareum but not in your local config
  2. Stale assignments - exist in your config but were deleted from Vocareum
  3. Settings drift - settings in Vocareum differ from your local config
  4. Content drift - files in Vocareum differ from your local files (opt-in via --content)

This is useful when:

  • You've created assignments directly in the Vocareum UI
  • You're onboarding an existing course to Git-based management
  • Assignments were created or deleted by another team member
  • Settings were changed in Vocareum UI and you want to sync them locally
  • Files were edited directly in Vocareum and you want to pull those changes
vocgit pull                # Interactive mode (no content drift check)
vocgit pull --verbose      # Show detailed output
vocgit pull --non-interactive  # Skip all issues

Content drift detection is opt-in. By default, vocgit pull (and vocgit pull --batch) does not download remote files to diff them — direct file edits in the Vocareum UI are NOT reconciled unless you ask for them. Add --content to enable the check. You can scope it with --assignment <name|id> (repeatable) and --part <part_id> (a part's part_id, not its directory name; requires exactly one --assignment):

vocgit pull --content                                  # check all assignments for content drift
vocgit pull --batch --content                          # batch sync including content drift
vocgit pull --content --assignment lab1                # scope to lab1 only
vocgit pull --content --assignment lab1 --part <part_id>  # scope to one part by its part_id

--skip-content is a separate flag that controls orphan-import behavior only — it tells vocgit to skip downloading files for newly imported orphan assignments (useful to retry after a failed pull). It has no effect on content drift detection.

Remote content downloads fail closed if a pull would exceed built-in safety limits: 5,000 files, 100 MiB for any single file, or 500 MiB total for one downloadContent pass. These limits protect local machines and CI runners from unexpectedly large or malformed remote file listings.

For orphaned assignments (in Vocareum, not in config):

  • Import: Download content and add to your local repository
  • Exclude: Hide from future scans (add to excluded_assignments)
  • Skip: Do nothing

For stale assignments (in config, deleted from Vocareum):

  • Reset ID: Clear assignment_id to allow re-creation from template
  • Remove: Delete the assignment from config entirely
  • Exclude: Keep in config but skip during sync
  • Skip: Do nothing

For settings drift (local settings differ from Vocareum):

  • Pull: Update local config with settings from Vocareum
  • Keep: Keep local settings (will overwrite Vocareum on next push)
  • Skip: Do nothing for now

Set publish_options.sync_settings: false to skip course, assignment, and part settings sync while still syncing files. Assignments and parts can override this with their own sync_settings value; part settings take precedence over assignment settings, which take precedence over the global publish option. Disabled settings remain in vocareum.yaml but are ignored for drift detection and push updates.

For content drift (files in Vocareum differ from local — requires --content):

  • Pull: Download remote files (overwrites local files)
  • Keep: Keep local files (will overwrite Vocareum on next push)
  • Skip: Do nothing for now

Example workflow (with --content to include content drift):

$ vocgit pull --content

ℹ Scanning for assignment sync issues...
ℹ Found 1 orphaned assignment(s) in Vocareum.

[1/1] Lab 3: Advanced Topics (ID: 555666)
? What would you like to do? Import to local repository
? Local directory name: lab3-advanced
  Part 1/2: downloaded 5 files
  Part 2/2: downloaded 3 files
✓ Imported "Lab 3: Advanced Topics" to lab3-advanced/

ℹ Found 1 stale assignment(s) in config (deleted from Vocareum).

[1/1] Old Lab (ID: 777888, path: old-lab)
? This assignment was deleted from Vocareum. What would you like to do?
  Reset ID (allow re-creation from template)
✓ Reset ID for "Old Lab" - will be re-created on next push

ℹ Found 1 assignment(s) with settings drift.

[1/1] Lab 1: Introduction (ID: 11111)
  Part "Part 1" settings changed:
    - session_length: "60" → "120"
    - cloud_labs: false → true
? What would you like to do? Pull settings from Vocareum (update local config)
✓ Will update local settings for "Lab 1: Introduction"

ℹ Found 1 assignment(s) with content changes on Vocareum.

[1/1] Lab 2: Data Analysis (ID: 22222)
  Content changes:
    ~ docs/README.md (modified)
    + scripts/new_test.py (new on remote)
? What would you like to do? Pull remote files (overwrite local)
✓ Pulled content changes for "Lab 2: Data Analysis"

Summary:
  Imported:        1
  Settings pulled: 1
  Content pulled:  1
  Excluded:        0
  Removed:         0
  Reset:           1
  Skipped:         0

ℹ Updated vocareum.yaml

Throttling the Vocareum API

vocgit schedules all Vocareum API calls through a built-in request throttle to avoid hitting rate limits, especially when pulling or pushing many assignments. The throttle is configurable via a vocareum.throttle block in vocareum.yaml:

vocareum:
  org_id: "..."
  course_id: "..."
  throttle:
    max_concurrency: 1
    min_interval_ms: 300
    jitter: true

| Field | Default | Range | Description | |-------|---------|-------|-------------| | max_concurrency | 1 | 1–5 | Maximum number of concurrent Vocareum API requests | | min_interval_ms | 300 | 0–60000 | Minimum milliseconds between request starts | | jitter | true | — | Add random jitter to the start spacing to avoid thundering herd |

Requests are FIFO-scheduled: each request waits until both the concurrency slot and the minimum interval are satisfied before starting. Jitter applies to the start spacing only — it does not affect retry backoff.

Environment variable overrides (take precedence over vocareum.yaml):

| Variable | Overrides | |----------|-----------| | VOCAREUM_MAX_CONCURRENCY | vocareum.throttle.max_concurrency | | VOCAREUM_MIN_REQUEST_INTERVAL_MS | vocareum.throttle.min_interval_ms | | VOCAREUM_THROTTLE_JITTER | vocareum.throttle.jitter ("true" / "false") |

CI note: if you run vocgit from multiple GitHub Actions runners against the same course concurrently, use a concurrency: group to serialize them rather than raising max_concurrency:

concurrency:
  group: vocareum-publish-${{ github.repository }}
  cancel-in-progress: false

GitHub Action

The Action is a composite action: it installs the published vocgit CLI (pinned to the action's version) and runs vocgit push. It supports both v2 token auth and v3 OAuth.

v2 token auth:

name: Push to Vocareum
on:
  push:
    branches: [main]
    paths: ['lab*/**', 'vocareum.yaml']

jobs:
  push-to-vocareum:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5

      - name: Push to Vocareum
        uses: ddlin/vocareum-publisher@v1
        with:
          config-file: vocareum.yaml
          api-key: ${{ secrets.VOCAREUM_API_KEY }}
          non-interactive: true

v3 OAuth:

      - name: Push to Vocareum (v3 OAuth)
        uses: ddlin/vocareum-publisher@v1
        with:
          auth: oauth
          client-id: ${{ secrets.VOCAREUM_OAUTH_CLIENT_ID }}
          client-secret: ${{ secrets.VOCAREUM_OAUTH_CLIENT_SECRET }}
          non-interactive: true

Supported action inputs (action.yml): config-file, root (workspace root, default .), api-key, auth, client-id, client-secret, dry-run, non-interactive, assignment, part, force-all, sync-deletes, auto-commit (ignored in CI), verbose. Output: success. Requires Node.js (GitHub-hosted runners include it). api-key is optional — omit it when using auth: oauth.

Directory Structure

course-repo/
├── vocareum.yaml         # Configuration
├── lab1-intro/
│   └── part1/
│       ├── startercode/  # Student-visible starter code
│       ├── scripts/      # Grading scripts
│       ├── lib/          # Grading libraries (hidden)
│       ├── asnlib/       # Assignment libraries
│       ├── docs/         # Documentation
│       ├── data/         # Datasets
│       └── private/      # Private files
└── lab2-analysis/
    └── ...

Supported Directory Types

| Directory | Description | Synced | |-----------|-------------|--------| | startercode | Student-visible starter files | ✓ | | scripts | Grading and setup scripts | ✓ | | lib | Grading libraries (hidden from students) | ✓ | | asnlib | Assignment libraries | ✓ | | docs | Documentation files | ✓ | | data | Datasets and resources | ✓ | | private | Private course files | ✓ | | course | Course-level shared files | ✗ |

Note: The course directory is NOT synced. It contains course-wide shared files (symlinks) that are shared across all assignments. Syncing these would cause infinite update loops. Manage course-level files directly in the Vocareum UI.

Configure which directories to sync per part:

parts:
  - part_id: "123"
    path: "part1"
    directories: ["startercode", "scripts", "lib"]  # Only sync these

Important Notes

All IDs Are Strings

Vocareum API returns all IDs as strings. Always use string types:

# Correct
assignment_id: "12345"

# Wrong
assignment_id: 12345

Local Creation, CI/CD Updates

  • Create assignments locally using vocgit new
  • Commit IDs to Git before CI/CD runs
  • CI/CD only updates existing assignments

Template Selection

Templates can exist in any course within your organization. When you have multiple templates configured, vocgit new will prompt you to select which template to use:

$ vocgit new lab3
Multiple templates available.
? Select template for this assignment:
❯ Standard Lab (99999)
  Cloud Lab (course:11111, id:88888)
  Timed Exam (77777)

Templates in the same course as your main course_id show just the ID. Templates in different courses show both the course and assignment ID for clarity.

The selected template ID is stored per-assignment in vocareum.yaml:

assignments:
  - name: "Lab 3"
    path: "lab3"
    template_assignment_id: "88888"  # Selected: Cloud Lab

Never Auto-Commit in CI/CD

The auto_commit option should only be used locally. In CI/CD it is force-disabled by the CLI.

Push Confirmation Behavior

  • Local CLI prompts for confirmation before executing push.
  • --non-interactive skips prompts.
  • CI/GitHub Actions automatically run non-interactive.

API Contract Notes

  • Authentication header: Authorization: Token <token>
  • Base API path: https://api.vocareum.com/api/v2/
  • Assignment copy: POST /api/v2/courses/{courseId}/assignments with body:
    • { "method": "copy", "source": "<templateAssignmentId>", "name": "<newName>" }
    • Polls transaction endpoint for up to 60 seconds until complete
  • Content updates: part PUT with content[].zipcontent (base64 zip)
    • Uses reset: 1 to clear directory before upload (ensures exact Git state)
    • All files in directory uploaded together as a single ZIP
  • Part updates may return transactionid; CLI polls GET /api/v2/transaction/{id}
  • Failed push runs are stored in publish_history with status: failed and failed[] entries

ID Discovery

When an assignment or part ID is missing from config but exists in Vocareum:

  • Assignment IDs are discovered by name lookup (prevents duplicate creation)
  • Part IDs are discovered by seqnum mapping
  • Discovered IDs are automatically saved to vocareum.yaml

API Credentials

To use vocgit, you need a Vocareum Personal Access Token with the appropriate permissions.

Generating a Token

  1. Log in to Vocareum Labs
  2. Go to Profile > Settings > Personal Access Tokens
  3. Click Generate New Token
  4. Enter a description (e.g., "git-api")
  5. Set Token scope to Global
  6. Select the required permissions (see below)
  7. Click Generate and copy the token immediately (it won't be shown again)

Required Permissions

Select the following permissions when creating your token:

| Category | Permissions | Notes | |----------|-------------|-------| | courses | GET: List courses | | | assignments | GET: List assignments for a course | | | | POST: Create or copy an assignment for a course | | | | PUT: Update an assignment for a course | | | parts | GET: List parts for an assignment | | | | PUT: Update a part's data content | | | files | GET: Get the URL of a content file | | | rubrics | GET, POST, PUT, DELETE | Optional (future feature) |

All other permissions are optional.

Token permissions - part 1 Token permissions - part 2

Storing Your Token

For local CLI use:

export VOCAREUM_API_KEY="your-token-here"

Or add to your shell profile (~/.bashrc, ~/.zshrc).

For GitHub Actions:

  1. Go to your repository's Settings > Secrets and variables > Actions
  2. Click New repository secret
  3. Name: VOCAREUM_API_KEY
  4. Value: Your token

Authentication: v2 Token vs v3 OAuth

vocgit supports two authentication modes:

| Mode | Flag / Env | Credential env vars | API base | |------|-----------|---------------------|----------| | token (default) | --auth token / VOCAREUM_AUTH_MODE=token | VOCAREUM_API_KEY or VOCAREUM_API_TOKEN | https://api.vocareum.com/api/v2 | | oauth (opt-in) | --auth oauth / VOCAREUM_AUTH_MODE=oauth | VOCAREUM_OAUTH_CLIENT_ID + VOCAREUM_OAUTH_CLIENT_SECRET | https://labs.vocareum.com/api/v3 |

v2 token (default) — Set VOCAREUM_API_KEY (or the alias VOCAREUM_API_TOKEN) to your Personal Access Token. Requests carry Authorization: Token <token> against https://api.vocareum.com/api/v2. No additional configuration needed.

v3 OAuth (opt-in) — Set VOCAREUM_OAUTH_CLIENT_ID and VOCAREUM_OAUTH_CLIENT_SECRET and select the mode via --auth oauth or VOCAREUM_AUTH_MODE=oauth. vocgit performs an OAuth client-credentials exchange at https://labs.vocareum.com/api/v3/oauth/token, caches the resulting access token for the lifetime of the process, and retries automatically on a single 401 response. Requests carry Authorization: Bearer <access_token> against https://labs.vocareum.com/api/v3.

Optional URL overrides for v3 OAuth:

| Variable | Default | |----------|---------| | VOCAREUM_API_V3_BASE_URL | https://labs.vocareum.com/api/v3 | | VOCAREUM_OAUTH_TOKEN_URL | https://labs.vocareum.com/api/v3/oauth/token |

Security guidance

Prefer environment variables or a secrets manager over CLI flags:

  • --client-id / --client-secret CLI flags exist but are discouraged — they appear in shell history and process listings.
  • Never put OAuth credentials in vocareum.yaml; the file is committed to Git.

Usage examples

# Opt in per-invocation
vocgit push --auth oauth

# Opt in for the whole shell session
export VOCAREUM_AUTH_MODE=oauth
vocgit pull
vocgit push

CI / GitHub Actions example

Store credentials as repository secrets (VOCAREUM_OAUTH_CLIENT_ID, VOCAREUM_OAUTH_CLIENT_SECRET) and pass them as environment variables in your workflow step:

- name: Push to Vocareum (v3 OAuth)
  env:
    VOCAREUM_AUTH_MODE: oauth
    VOCAREUM_OAUTH_CLIENT_ID: ${{ secrets.VOCAREUM_OAUTH_CLIENT_ID }}
    VOCAREUM_OAUTH_CLIENT_SECRET: ${{ secrets.VOCAREUM_OAUTH_CLIENT_SECRET }}
  run: vocgit push --non-interactive

Environment Variables

| Variable | Description | |----------|-------------| | VOCAREUM_API_KEY | v2 Personal Access Token (default auth mode) | | VOCAREUM_API_TOKEN | Alias for VOCAREUM_API_KEY | | VOCAREUM_AUTH_MODE | Auth mode: token (default) or oauth | | VOCAREUM_OAUTH_CLIENT_ID | v3 OAuth client ID (required when VOCAREUM_AUTH_MODE=oauth) | | VOCAREUM_OAUTH_CLIENT_SECRET | v3 OAuth client secret (required when VOCAREUM_AUTH_MODE=oauth) | | VOCAREUM_API_V3_BASE_URL | Override the v3 API base URL (default: https://labs.vocareum.com/api/v3) | | VOCAREUM_OAUTH_TOKEN_URL | Override the v3 token endpoint URL (default: https://labs.vocareum.com/api/v3/oauth/token) | | VOCAREUM_MAX_CONCURRENCY | Override vocareum.throttle.max_concurrency (1–5) | | VOCAREUM_MIN_REQUEST_INTERVAL_MS | Override vocareum.throttle.min_interval_ms (0–60000 ms) | | VOCAREUM_THROTTLE_JITTER | Override vocareum.throttle.jitter (true / false) | | VOCAREUM_LOG_LEVEL | Log level: ERROR, WARN, INFO, DEBUG, TRACE |

License

MIT License - see LICENSE for details.

Links