Publish a service
Publish a service from the dashboard or with the CLI, and learn what every field does.
This page explains how to describe your service to Varis and publish it. If you want the shortest path, see Quickstart: publish a service.
Before you begin
- Create a Varis account.
- Deploy your endpoint to a public
httpsaddress. - Add
verifyRequestto your endpoint. For more information, see Handle requests.
Service fields
Every service has the same fields, whether you publish from the dashboard or with the CLI.
| Field | Required | Description |
|---|---|---|
| Name | Yes | A readable name, up to 128 characters. |
| Slug | Yes | A permanent ID for the service within your owner, such as convert-currency. Use lowercase letters, numbers, and single hyphens, up to 64 characters. |
| Description | Yes | What the service does, in 20 to 1,024 characters. Agents read it to decide whether to call your service. |
| Instructions | No | How agents should use the service when the input fields can't say it, such as another service to call first. Up to 2,000 characters. |
| Type | Yes | One of data, content, tool, skill, compute, memory, storage, model, or messaging. |
| Categories | Yes | One or more categories from the list of categoriesAPI. |
| Price | No | Your price per call, in whole US cents. You receive all of it. The default is 0, which makes the service free. |
| Endpoint URL | Yes | The address Varis calls. See Endpoint rules. |
| Method | No | GET or POST. The default is GET. See Choose GET or POST. |
| Input schema | No | The fields your service takes. If you leave it out, your service takes no input. |
| Output schema | Yes | The fields your service returns. |
Write the description and instructions for agents, not for people. An agent picks your service based on what you write there.
The slug is permanent. If you change a slug and publish again, Varis creates a second service instead of renaming the first.
Publish your service
- In the dashboard, go to Services.
- Click Add service.
- Fill in Name, Slug, and Description.
- Fill in Instructions (optional).
- Choose a Type and at least one category.
- In Price per request (in cents), enter a price, or enter
0for a free service. - Enter the Endpoint URL, and choose a Method.
- If your service takes input, click Add field under Input schema for each field. For each field, enter a key, choose a type, and choose Required or Optional.
- Under Output schema, add each field your service returns in the same way.
- Click Publish service.
Your service is live, and agents can find it.
Varis saves your service as a draft while you fill in the form. If you close the form before you publish, open the draft from Services to finish it.
Declare services in code
This section applies to the CLI only.
I/O Types
The CLI turns your Input and Output types into JSON Schemas when you publish. Write both type arguments. TypeScript can't infer them, and the build fails without them.
You can use strings, numbers, booleans, null, literals and literal unions, arrays, objects, optional fields, index signatures, and unions of those. A field marked with ? is optional. Every other field is required.
You can't use any, unknown, bigint, symbol, functions, classes with methods, Date, Map, Set, Promise, tuples, or recursive types. Send dates as strings.
If your service takes no input, use void as the input type:
varis.services.define<void, Output>({
// ...rest of the service definition.
})Comments
Comments on your fields become descriptions in the schema, and agents read them. Write them for agents. A comment above the field or at the end of its line works, in any comment style.
type Input = {
/** ISO 4217 code of the currency to convert from. */
from: string;
// ISO 4217 code of the currency to convert to.
to: string;
amount: number; // The amount to convert.
}A comment above the Input or Output type describes the whole schema.
/** Pass the argument:
* `from` and `to`: ISO 4217 code of the currencies.
* `amount`: integer in the lowest denomination of the `from` currency.
* */
type Input = {
from: string;
to: string;
amount: number;
}Comments are read into the schema as field (or schema) descriptions. Use them to give agents better context.
To keep a comment out of your published service, leave a blank line between the comment and the field or type. Use this for internal notes, such as TODOs, that agents shouldn't see.
type Input = {
// TODO: add support for historical rates.
/** ISO 4217 code of the currency to convert from, such as USD. */
from: string;
// ..
};Agents see the description of from. They don't see the TODO.
Literal values
The CLI reads define from your source code. It doesn't run your code. Every value you pass to define must be written out in full. An environment variable or any other computed value fails the build, and the CLI tells you the file and line.
Endpoint address
Varis needs a full endpoint URL for every service. You give it one in either of two ways:
endpoint_url: the full address, such ashttps://api.example.com/currency/convert. Varis uses it as written.path: only the path, such as/currency/convert. Varis joins it to thebase_urlinvaris.jsonto build the endpoint URL.
Use path if your services share one host. The set base_url allows you to change the host in one place instead of in every define call.
To set base_url, run:
varis init --base-url https://api.example.comIf you set endpoint_url on a service, Varis uses it and ignores path and base_url for that service. This lets you point one service at a different host.
If you set path but varis.json has no base_url, varis build fails.
base_url is your production address, and it lives in varis.json with your code, not in an environment variable. That way, a staging address can't ship by mistake.
Publish one service
To publish only one service from a project with several, pass its slug:
varis publish convert-currencyvaris.json
The first time you run varis publish, the CLI creates varis.json and writes your services to it. Commit it with your code. It contains your owner's ID, which isn't a secret, and it never contains a credential.
For more information, see varis.json.
Choose GET or POST
The method decides how your input reaches your endpoint.
GET | POST | |
|---|---|---|
| Where the input goes | The query string | A JSON body |
| Input shape | Flat: strings, numbers, booleans, literal unions, and arrays of those | Any supported shape, including nested objects |
| Numbers and booleans | Arrive as strings, so you parse them | Arrive as JSON values |
| Logged by your server | Yes, in your access logs | Usually not |
Use GET if your endpoint already reads query parameters and your input is flat. Use POST if your input is nested or contains anything sensitive.
For GET, an array repeats its key, such as ?tag=a&tag=b. Varis sends only the fields declared in your input schema, and it leaves out null values and empty arrays.
Endpoint rules
Varis accepts an endpoint URL only if it meets these rules:
- It uses
https. - It's publicly reachable. Varis rejects
localhostand private addresses. - It has no query string or fragment. Declare query values as input fields instead.
Varis never follows redirects. A redirect counts as a failed call, and the agent isn't charged. Publish the final address. Common causes of redirects are a trailing slash, http to https, and www to the bare domain.
To test against localhost before you publish, see Local development.
What's next
- Handle requests: what Varis sends to your endpoint and what it expects back.
- Update a service.