Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/paramveer-cyber/Deployaar/llms.txt

Use this file to discover all available pages before exploring further.

Deployaar offers three billing plans managed through Razorpay. Plan limits are enforced server-side on every mutation inside packages/services/billing/limits.ts — there is no client-side trust. When a limit is exceeded, the server throws a FORBIDDEN error with an upgrade message explaining exactly what the current plan allows and that an upgrade is required.

Plan Comparison

FeatureFreeProPro Max
Max Projects1515
Max Feature Requests325100
AI ProvidersGoogle onlyGoogle + OpenAIAnthropic + OpenAI + Google + DeepSeek
Included Modelsgemini-2.0-flashgemini-1.5-pro, gpt-4oAll models (no restriction)
Price (INR)Free₹1,499₹2,999
PR review always uses Anthropic regardless of the active plan — ANTHROPIC_API_KEY must be set in your environment even if you are on the Free plan and want AI-powered pull request review to work.

Limit Enforcement

Before any project or feature request is created, Deployaar runs an async guard that queries the organization’s billing information, fetches the plan limits, and compares against the current usage count.

assertProjectLimit(organizationId)

Called by the project.create tRPC procedure before inserting a new project row. It counts all existing projects in the organization and compares that number against planLimitsMap[plan].maxProjects. If the limit is already reached, it throws:
Your Free plan allows up to 1 project. Upgrade to create more.

assertFeatureRequestLimit(projectId)

Called by the featureRequest.create tRPC procedure before inserting a new feature request. It resolves the project’s parent organization and counts all feature requests across the organization, comparing against planLimitsMap[plan].maxFeatureRequests. If the limit is already reached, it throws:
Your Pro plan allows up to 25 feature requests. Upgrade to create more.

Upgrading

Upgrading from Free to Pro or Pro Max is a two-step flow:
1

Create an Order

Call the billing.createOrder tRPC procedure (or POST /billing/orders), passing the organizationId and targetPlan ("pro" or "pro_max"). The server creates a Razorpay order and returns the orderId, amount, currency, and keyId needed to open the Razorpay checkout widget in the browser.
2

Complete Payment in the Browser

Open the Razorpay checkout widget using the values returned in step 1. When the user completes payment, Razorpay returns razorpayOrderId, razorpayPaymentId, and razorpaySignature.
3

Verify the Payment

Call billing.verifyPayment (or POST /billing/verify) with the three Razorpay values and the targetPlan. The server verifies the HMAC-SHA256 signature using RAZORPAY_KEY_SECRET, then upgrades the organization’s plan in the database.
In addition to the client-initiated verify flow, Razorpay delivers asynchronous webhook events to POST /api/razorpay/webhook. The webhook handler verifies the payload signature using RAZORPAY_WEBHOOK_SECRET and processes the following events:
Webhook EventAction
payment.capturedUpgrades plan to targetPlan, sets billing status to active
payment.failedSets billing status to past_due
subscription.cancelledSets billing status to inactive
Only organization owners and admins can create orders or verify payments. Members with the member role will receive a FORBIDDEN error if they attempt to manage billing.

Model Access Enforcement

Before any AI call is dispatched, assertModelAllowedForOrg is called with the organization ID, the requested provider, and the requested model string. It resolves the plan limits and performs two checks:
  1. Provider check — Is the requested provider string in limits.allowedAiProviders? If not, throws FORBIDDEN with a message like: Your Free plan does not include access to the "anthropic" provider. Upgrade to unlock more models.
  2. Model check — If limits.allowedModels is non-empty, is the requested model in that list? If not, throws FORBIDDEN with a message like: Your Pro plan does not include access to model "claude-sonnet-4-6". Upgrade to unlock more models.
The Pro Max plan sets allowedModels: [] (an empty array), which the enforcement logic treats as no model restriction — all models for the allowed providers are accessible.

Plan Limits Code Reference

The canonical source of truth for all plan limits is the planLimitsMap constant in packages/services/billing/limits.ts:
export const planLimitsMap = {
  free: {
    maxProjects: 1,
    maxFeatureRequests: 3,
    displayName: "Free",
    allowedAiProviders: ["google"],
    allowedModels: ["gemini-2.0-flash"],
  },
  pro: {
    maxProjects: 5,
    maxFeatureRequests: 25,
    displayName: "Pro",
    allowedAiProviders: ["google", "openai"],
    allowedModels: ["gemini-1.5-pro", "gpt-4o"],
  },
  pro_max: {
    maxProjects: 15,
    maxFeatureRequests: 100,
    displayName: "Pro Max",
    allowedAiProviders: ["anthropic", "openai", "google", "deepseek"],
    allowedModels: [], // empty = all models allowed
  },
};
The helper getLimitsForPlan(billingPlan: string): PlanLimits resolves a plan key to its limits object, falling back to planLimitsMap.free if an unrecognised plan string is encountered. This means unknown plan values always default to the most restrictive tier.

Checking the Current Plan

The billing.getCurrentPlan tRPC procedure (or GET /billing/{organizationId}) returns the full current plan state for an organization:
{
  billingPlan: "free" | "pro" | "pro_max";
  billingStatus: "active" | "inactive" | "past_due";
  displayName: string;
  maxProjects: number;
  maxFeatureRequests: number;
  currentProjectCount: number;
  currentFeatureRequestCount: number;
}
Use this response to render usage meters or upgrade prompts in the dashboard.

Build docs developers (and LLMs) love