Plugin Reference
Complete reference for creating JSON-based plugins in Invoice Radar
Overview
Invoice Radar plugins are defined using JSON configuration files that specify how to authenticate with a service and extract documents. This reference covers the complete plugin structure and configuration options.
Plugin Structure
A plugin consists of several main sections:
{
"$schema": "https://raw.githubusercontent.com/invoiceradar/plugins/main/schema.json",
"id": "example-service",
"name": "Example Service",
"description": "Short description of the Example Service",
"homepage": "https://example.com",
"autofill": true,
"configSchema": {
// Configuration options
},
"startAuth": [
// Authentication steps
],
"checkAuth": [
// Authentication verification steps
],
"getConfigOptions": [
// Optional: Extract configuration options
],
"getDocuments": [
// Document extraction steps
]
}
Core Properties
Basic Metadata
Property | Type | Required | Description |
---|---|---|---|
$schema | string | No | URL to the JSON schema for validation |
id | string | Yes | Unique identifier for the plugin |
name | string | Yes | Display name of the plugin |
description | string | No | Brief description of what the plugin does |
homepage | string | No | URL of the service (used for logo and linking) |
Configuration Schema
Define user-configurable options using the configSchema
property:
{
"configSchema": {
"teamId": {
"type": "string",
"title": "Team ID",
"description": "The ID of your team",
"required": true,
"example": "team_abc123"
},
"apiKey": {
"type": "password",
"title": "API Key",
"description": "Your API key for authentication",
"required": true
},
"environment": {
"type": "string",
"title": "Environment",
"description": "Select the environment",
"options": [
{ "value": "production", "label": "Production" },
{ "value": "staging", "label": "Staging" }
],
"default": "production"
},
"downloadReceipts": {
"type": "boolean",
"title": "Download Receipts",
"description": "Download receipts for each invoice",
"default": false
}
}
}
Configuration Property Types
Type | TypeScript Type | Description |
---|---|---|
string | string | Text input field |
password | string | Password input field (masked) |
number | number | Numeric input field |
boolean | boolean | Checkbox input |
Configuration Property Options
Property | Type | Description |
---|---|---|
title | string | Display label for the field |
description | string | Help text explaining the field |
required | boolean | Whether the field is required |
default | string | number | boolean | Default value |
example | string | Example value to show users |
hidden | boolean | Hide the field from users |
options | Array<{value: string, label: string}> | Dropdown options |
Plugin Flows
Authentication Flow (startAuth
)
Steps to authenticate a user who isn't logged in:
{
"startAuth": [
{
"action": "navigate",
"url": "https://example.com/login"
},
{
"action": "waitForElement",
"selector": "#login-form"
}
]
}
Authentication Check (checkAuth
)
Steps to verify if a user is already authenticated:
{
"checkAuth": [
{
"action": "navigate",
"url": "https://example.com/dashboard"
},
{
"action": "checkElementExists",
"selector": "#user-menu"
}
]
}
Configuration Options (getConfigOptions
)
Optional steps to extract configuration options like team IDs or project lists. These will be exposed to the user as a dropdown in the configuration modal.
{
"configSchema": {
"teamId": {
"type": "string",
"title": "Team ID",
"description": "The ID of your team",
"required": true,
"example": "team_abc123"
}
},
"getConfigOptions": [
{
"action": "navigate",
"url": "https://example.com/settings"
},
{
"action": "extractAll",
"selector": ".team-item",
"variable": "team",
"fields": {
"id": ".team-id",
"name": ".team-name"
},
"forEach": [
{
"action": "exposeOption",
"config": "teamId",
"option": "{{team}}"
}
]
}
]
}
Document Extraction (getDocuments
)
Steps to find and download documents:
{
"getDocuments": [
{
"action": "navigate",
"url": "https://example.com/invoices"
},
{
"action": "extractAll",
"selector": ".invoice-row",
"variable": "invoice",
"fields": {
"id": ".invoice-id",
"date": ".invoice-date",
"total": ".invoice-total",
"url": ".download-link[href]"
},
"forEach": [
{
"action": "downloadPdf",
"url": "{{invoice.url}}",
"document": "{{invoice}}"
}
]
}
]
}
Using Configuration Variables
Access user configuration within steps using template syntax:
{
"action": "navigate",
"url": "https://example.com/team/{{teamId}}/invoices"
}
Step Reference
For detailed information about available steps, see the Steps Reference documentation.
Autofill Configuration
Invoice Radar automatically detects and fills provided login credentials (username, password, OTP) and submits the authentication form to streamline the login process.
Default Behavior
By default, autofill
is set to true
, which enables automatic input detection for:
- Username (also works for email fields)
- Password
- OTP (One-Time Password/2FA codes)
- Submit (automatically submits the form after filling credentials)
When enabled, Invoice Radar will automatically detect and fill these fields during the authentication process, then submit the form to complete the login.
{
"autofill": true
}
Customization Options
You can customize or disable autofill for individual fields by setting each property (username
, password
, otp
, submit
) to either:
false
- Disables autofill for that specific field- Configuration object - Customizes the behavior with these options:
selector
: Custom CSS selector if the default detection doesn't worktitle
: Custom label for the field in the UI (e.g., "Email" instead of "Username")
Autofill Field Options
Field | Type | Description |
---|---|---|
username | boolean | object | Username/email field configuration |
password | boolean | object | Password field configuration |
otp | boolean | object | One-time password field configuration |
submit | boolean | object | Submit button configuration |
Each field can be:
true
: Enable with automatic detectionfalse
: Disable the fieldobject
: Custom configuration withselector
and optionaltitle
Configuration Examples
Disable Automatic Submission
{
"autofill": {
"submit": false
}
}
Custom Selectors
In case the default autofill doesn't work, you can provide custom selectors for each field.
{
"autofill": {
"username": {
"selector": "#email-input",
"title": "Email Address"
},
"password": {
"selector": "#password-input"
},
"otp": false,
"submit": {
"selector": "#login-button"
}
}
}
User Agent Override
{
"userAgentOverride": "Mozilla/5.0 (compatible; CustomBot/1.0)"
}
You can override the browser's user agent string. Set to true
to use a default override, or provide a custom string.
Examples
Basic Plugin
{
"id": "simple-service",
"name": "Simple Service",
"description": "Short description of the Simple Service",
"homepage": "https://simple.com",
"startAuth": [
{
"action": "navigate",
"url": "https://simple.com/login"
}
],
"checkAuth": [
{
"action": "checkURL",
"url": "https://simple.com/dashboard"
}
],
"getDocuments": [
{
"action": "navigate",
"url": "https://simple.com/invoices"
},
{
"action": "extractAll",
"selector": ".invoice",
"variable": "invoice",
"fields": {
"id": ".id",
"date": ".date",
"total": ".total"
},
"forEach": [
{
"action": "printPdf",
"document": "{{invoice}}"
}
]
}
]
}
Advanced Plugin with Configuration
{
"id": "advanced-service",
"name": "Advanced Service",
"description": "Extract invoices with team support",
"homepage": "https://advanced.com",
"autofill": {
"username": {
"title": "Email"
},
"submit": {
"selector": "#sbmt-btn"
}
},
"configSchema": {
"teamId": {
"type": "string",
"title": "Team ID",
"required": true
},
"includeArchived": {
"type": "boolean",
"title": "Include Archived Invoices",
"default": false
}
},
"autofill": {
"username": {
"selector": "#email",
"title": "Email"
},
"password": true,
"otp": false
},
"startAuth": [
{
"action": "navigate",
"url": "https://advanced.com/login"
}
],
"checkAuth": [
{
"action": "checkElementExists",
"selector": "#user-avatar"
}
],
"getConfigOptions": [
{
"action": "extractAll",
"selector": ".team-option",
"variable": "team",
"fields": {
"value": "[data-team-id]",
"label": ".team-name"
},
"forEach": [
{
"action": "exposeOption",
"config": "teamId",
"option": "{{team}}"
}
]
}
],
"getDocuments": [
{
"action": "navigate",
"url": "https://advanced.com/{{teamId}}/invoices"
},
{
"action": "if",
"script": "'{{includeArchived}}' === 'true'",
"then": [
{
"action": "click",
"selector": "#include-archived"
}
]
},
{
"action": "extractAll",
"selector": ".invoice-item",
"variable": "invoice",
"fields": {
"id": ".invoice-number",
"date": ".invoice-date",
"total": ".invoice-amount",
"downloadUrl": ".download-btn[href]"
},
"forEach": [
{
"action": "downloadPdf",
"url": "{{invoice.downloadUrl}}",
"document": {
"id": "{{invoice.id}}",
"date": "{{invoice.date}}",
"total": "{{invoice.total}}"
}
}
]
}
]
}
Validation
Plugins are validated against the JSON schema. Common validation errors include:
- Missing required properties (
id
,name
,startAuth
,checkAuth
,getDocuments
) - Invalid step configurations
- Incorrect configuration schema types
- Missing
document
properties in PDF download steps
Best Practices
- Use descriptive IDs: Choose unique, descriptive plugin IDs
- Provide clear descriptions: Help users understand what the service does
- Handle errors gracefully: Use
optional: true
for non-critical steps - Use proper selectors: Prefer stable selectors over brittle ones
- Test thoroughly: Verify the plugin works across different scenarios
- Document configuration: Provide clear descriptions and examples for config options