---
title: Low-level definitions
editUrl: https://github.com/Cratis/Arc.TypeScript/edit/main/Documentation/commands/low-level-definitions.md
description: Keep Zod-backed defineCommand, defineQuery, and defineObservableQuery definitions when decorators do not fit, on the same pipelines as model-bound artifacts.
---


Model-bound classes are the default. Keep `defineCommand`, `defineQuery`, and `defineObservableQuery` when you already have Zod schemas, need explicit `validate` and `filters` callbacks, or integrate code that cannot use decorators. The definitions run through the **same pipelines** as model-bound artifacts.

```typescript
import { ArcServer, defineCommand, defineQuery } from '@cratis/arc.core';
import { z } from 'zod';

const tasks = new Map<string, string>();
const create = defineCommand({
    name: 'Create', namespace: 'Tasks', schema: z.object({ id: z.string(), title: z.string() }),
    handle: ({ id, title }) => { tasks.set(id, title); return id; }
});
const list = defineQuery({
    name: 'List', namespace: 'Tasks', schema: z.object({}),
    perform: () => [...tasks].map(([id, title]) => ({ id, title }))
});
const server = new ArcServer({ commands: [create], queries: [list] });
```

This registers two operations in memory. Host `server` with [`runArc`](/arc/backend/typescript/core/#host-a-low-level-server) or a [host adapter](/arc/backend/typescript/hosts/) to serve `POST /api/tasks/create` and `GET /api/tasks/list`. You can also pass the definitions to `ArcApplication.createBuilder({ commands: [create], queries: [list] })` next to model-bound artifacts.

## What differs from model-bound artifacts

- The Zod schema, not field decorators, controls the input and its JSON Schema. Schemas must convert to JSON Schema; see [Command filters](/arc/backend/typescript/commands/command-filters/#keep-the-schema-for-shape).
- Services are declared with `handlerDependencies` and `validatorDependencies` and resolved with `currentServices()`; see [Dependency injection](/arc/backend/typescript/dependency-injection/#low-level-services).
- Validation uses `validate` and `filters`; see [Command filters](/arc/backend/typescript/commands/command-filters/).
- Commands can declare [execution scopes](/arc/backend/typescript/commands/command-execution-scopes/).
- Authorization is a property: `authorization: { roles: ['editor'] }`, plus an optional per-request `authorize(input, context)`; see [Authorizing commands and queries](/arc/backend/typescript/authorizing-commands-and-queries/).
- Client generation uses an explicit `clientOutput` contract and the [low-level manifest](/arc/backend/typescript/proxy-generation/low-level-manifest/).

Do not mix both representations for the **same** operation: duplicate names or routes are rejected at startup. The full list of definition fields is in [Configuration](/arc/backend/typescript/configuration/#low-level-definition-fields).

## Related

- [Query arguments](/arc/backend/typescript/queries/model-bound/query-arguments/), which apply to both kinds of query
- [Observable queries](/arc/backend/typescript/queries/observable-queries/) for `defineObservableQuery`
