Create a Prompt

Define reusable LLM instruction templates that can be versioned, scoped, and shared across plugins.

Last updated: 2026-04-06

Prompts are reusable LLM instruction templates stored in the platform. Instead of hardcoding prompt strings in your plugin code, you register prompts separately and load them at runtime with self.get_prompt(). This lets you update prompts without redeploying plugins, share prompts across teams, and manage prompt versions independently.


What Prompts Are

A prompt is a named text template with {{PLACEHOLDER}} markers that gets resolved at runtime. Prompts are stored in the platform and loaded by plugins using self.get_prompt(name). They are not executable on their own — they are inputs to the prompt_llm() service method.

  • Centralized — all prompt logic lives in one place, separate from plugin code
  • Versioned — the platform tracks prompt history so you can roll back to a previous version
  • Scoped — prompts can be user-level, tenant-level, or global, controlling who can access and modify them
  • Testable — update and test prompts without rebuilding or redeploying plugins

Benefits

BenefitWithout PromptsWith Prompts
Update LLM instructionsModify plugin code, rebuild, redeployUpdate the prompt via API — takes effect immediately
Share across pluginsCopy-paste prompt strings between pluginsBoth plugins call self.get_prompt("shared-classifier")
A/B testingDeploy two plugin versionsCreate two prompts, switch the name in pipeline config
RollbackRedeploy the previous plugin versionRevert the prompt to a previous version via API
Audit trailCheck git history for prompt changesPlatform tracks who changed what and when

Step 1 — Write the Template

Write your prompt template as a text string with {{PLACEHOLDER}} markers for dynamic content. Placeholders are replaced by your plugin code at runtime before being sent to the LLM.

financial-doc-classifier.txttext
You are a document classification expert.

Analyze the following document and classify it as exactly one of:
{{CATEGORIES}}

Document filename: {{FILENAME}}

Document content:
{{DOCUMENT_CONTENT}}

Rules:
1. Respond with ONLY the document type label.
2. Do not include any explanation or punctuation.
3. If the document does not match any category, respond with "unknown".
💡Tip

Use descriptive placeholder names that make the template self-documenting. Avoid generic names like {{INPUT}} or {{DATA}} — prefer {{DOCUMENT_CONTENT}}, {{FIELD_DEFINITIONS}}, {{CATEGORIES}}.


Step 2 — Choose a Scope

Prompts have three scope levels that control visibility and access:

ScopeVisibilityWho Can EditUse Case
userOnly the creating userThe creating user onlyPersonal experimentation and testing
tenantAll users in the tenant (organization)Tenant adminsShared across a team or organization — most common
globalAll users on the platformPlatform admins onlySystem-wide defaults provided by bizSupply
ℹ️Note

When a plugin calls self.get_prompt("name"), the platform resolves scope in order: user -> tenant -> global. A user-scoped prompt with the same name as a tenant-scoped prompt will take precedence for that user.


Step 3 — Register via the API

Register the prompt using the POST /prompts endpoint:

bash
curl -X POST https://api.bizsupply.com/v1/prompts \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "financial-doc-classifier",
    "scope": "tenant",
    "description": "Classifies financial documents into standard categories.",
    "template": "You are a document classification expert.\n\nAnalyze the following document and classify it as exactly one of:\n{{CATEGORIES}}\n\nDocument filename: {{FILENAME}}\n\nDocument content:\n{{DOCUMENT_CONTENT}}\n\nRules:\n1. Respond with ONLY the document type label.\n2. Do not include any explanation or punctuation.\n3. If the document does not match any category, respond with \"unknown\"."
  }'

The API returns the registered prompt:

json
{
  "id": "pmt_x7y8z9",
  "name": "financial-doc-classifier",
  "scope": "tenant",
  "version": 1,
  "description": "Classifies financial documents into standard categories.",
  "template": "You are a document classification expert...",
  "created_by": "usr_abc123",
  "created_at": "2026-01-15T10: 30: 00Z",
  "updated_at": "2026-01-15T10: 30: 00Z"
}

Step 4 — Verify

Confirm the prompt was registered by retrieving it:

bash
curl -X GET https://api.bizsupply.com/v1/prompts/financial-doc-classifier \
  -H "Authorization: Bearer YOUR_API_KEY"

="color:#5c6370;font-style:italic"># Response:
="color:#5c6370;font-style:italic"># {
="color:#5c6370;font-style:italic">#   "id": "pmt_x7y8z9",
="color:#5c6370;font-style:italic">#   "name": "financial-doc-classifier",
="color:#5c6370;font-style:italic">#   "version": 1,
="color:#5c6370;font-style:italic">#   "template": "You are a document classification expert..."
="color:#5c6370;font-style:italic"># }

Step 5 — Use in Plugins

Load the prompt in your plugin using self.get_prompt() and replace the placeholders with runtime values before sending to the LLM.

financial_classifier/plugin.pypython
from bizsupply_sdk import ClassificationPlugin


class FinancialClassifier(ClassificationPlugin):
    name = "financial-classifier"
    version = "1.0.0"

    CATEGORIES = [
        "invoice", "purchase_order", "receipt",
        "contract", "credit_note", "unknown",
    ]

    def classify(self, document) -> str:
        # Load the prompt template from the platform
        template = self.get_prompt("financial-doc-classifier")

        # Replace placeholders with runtime values
        prompt = template.replace(
            "{{CATEGORIES}}",
            "\n".join(f"- {cat}" for cat in self.CATEGORIES),
        ).replace(
            "{{FILENAME}}",
            document.filename,
        ).replace(
            "{{DOCUMENT_CONTENT}}",
            document.content[:4000],
        )

        # Send to the LLM
        result = self.prompt_llm(prompt, temperature=0.1)
        doc_type = result.strip().lower().replace(" ", "_")

        if doc_type not in set(self.CATEGORIES):
            return "unknown"

        return doc_type
⚠️Warning

If the prompt name does not exist, self.get_prompt() raises a PluginError. Always register the prompt before deploying the plugin, or wrap the call in a try/except to fall back to a default prompt.


Management Operations

Get a Prompt

bash
="color:#5c6370;font-style:italic"># Get latest version
curl -X GET https://api.bizsupply.com/v1/prompts/financial-doc-classifier \
  -H "Authorization: Bearer YOUR_API_KEY"

="color:#5c6370;font-style:italic"># Get a specific version
curl -X GET https://api.bizsupply.com/v1/prompts/financial-doc-classifier?version=2 \
  -H "Authorization: Bearer YOUR_API_KEY"

="color:#5c6370;font-style:italic"># List all prompts
curl -X GET https://api.bizsupply.com/v1/prompts \
  -H "Authorization: Bearer YOUR_API_KEY"

="color:#5c6370;font-style:italic"># List prompts filtered by scope
curl -X GET "https://api.bizsupply.com/v1/prompts?scope=tenant" \
  -H "Authorization: Bearer YOUR_API_KEY"

Update a Prompt

Updating a prompt creates a new version. The previous version is preserved in history.

bash
curl -X PUT https://api.bizsupply.com/v1/prompts/financial-doc-classifier \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template": "You are a senior document analyst...\n\n(updated template here)",
    "description": "Updated with improved classification accuracy."
  }'

="color:#5c6370;font-style:italic"># Response includes the new version number:
="color:#5c6370;font-style:italic"># { "version": 2, "updated_at": "2026-02-01T14:00:00Z" }

Delete a Prompt

bash
curl -X DELETE https://api.bizsupply.com/v1/prompts/financial-doc-classifier \
  -H "Authorization: Bearer YOUR_API_KEY"

="color:#5c6370;font-style:italic"># Response: { "deleted": true }
⚠️Warning

Deleting a prompt will cause any plugin that calls self.get_prompt("financial-doc-classifier") to fail with a PluginError. Make sure no active plugins reference the prompt before deleting.


Common Patterns

Classification Prompt

classification-prompt.txttext
You are a document classification expert.

Analyze the following document and classify it as exactly one of:
{{CATEGORIES}}

Document filename: {{FILENAME}}

Document content:
{{DOCUMENT_CONTENT}}

Respond with ONLY the document type label. No explanation.

Extraction Prompt

extraction-prompt.txttext
You are a document extraction expert.

Extract the following fields from this {{DOCUMENT_TYPE}} document:
{{FIELDS}}

Document content:
{{DOCUMENT_CONTENT}}

Rules:
1. Return ONLY a JSON object with field names as keys.
2. For each field, also include a {field_name}_confidence key with a value from 0.0 to 1.0.
3. If a field cannot be found, set its value to null.
4. For date fields, use ISO 8601 format (YYYY-MM-DD).
5. For number fields, return raw numbers without currency symbols or commas.

Contract Analysis Prompt

contract-analysis-prompt.txttext
You are a contract analysis expert specializing in {{CONTRACT_TYPE}} agreements.

Analyze the following contract and extract:
{{FIELDS}}

Pay special attention to:
- Renewal clauses and auto-renewal terms
- Termination conditions and notice periods
- Pricing escalation clauses
- Liability caps and indemnification

Contract content:
{{DOCUMENT_CONTENT}}

Return a JSON object with the extracted fields. Include a "risk_flags" array with any concerning clauses identified.

Next Steps

  • Create a Classification Plugin that loads prompts with self.get_prompt().
  • Create an Extraction Plugin with a separate extraction prompt template.
  • Create a Pipeline to wire your prompt-powered plugins into a processing flow.
  • Read the Plugin Service API Reference for details on prompt_llm() and get_prompt().