# /api/v1/instances (management)

Source-derived management endpoint contract, authentication, request validation, responses, and errors.

Source: https://docs.minds.sh/docs/api/platform/reference/management--api-v1-instances



This is the **management** service route. Its origin and authentication are described in [Platform API overview](/docs/api/platform) and [Authentication](/docs/api/platform/authentication). A path shared by another service is a different endpoint.

| Property                       | Contract                                                                       |
| ------------------------------ | ------------------------------------------------------------------------------ |
| Methods                        | POST, GET                                                                      |
| Path                           | `/api/v1/instances`                                                            |
| Path parameters                | None                                                                           |
| Query parameters read in route | `tenant_id`                                                                    |
| Headers read in route          | No additional direct header reads; authentication helpers may read credentials |

## Authentication and access [#authentication-and-access]

Management auth context: validated x-api-key or configured session authentication; trusted gateway integration may select its auth pipeline. Organization/tenant checks are separate.

## Request and response definitions [#request-and-response-definitions]

The following named definitions are imported or declared by this route. Optional markers, defaults, bounds, and enum values are shown exactly as implemented. A response type is a source contract, not an example populated with real account data.

### CreateInstanceRequest [#createinstancerequest]

```typescript
export interface CreateInstanceRequest {
  tenantId: string;
  instanceType: InstanceType;
  tierName: string; // "Starter", "Professional", etc.
  name?: string;
  region?: string;
  tags?: Record<string, string>;
}
```

Source: `minds-ui/apps/api-service/lib/services/instance-provisioning-service.ts:29`.

## Method behavior [#method-behavior]

The handler excerpt preserves field validation, response envelopes, cookie changes, and exception branches. Values returned by service helpers retain their named response type above; for passthrough routes, the upstream response is authoritative.

### POST [#post]

```typescript
export async function POST(request: NextRequest) {
  try {
    const authContext = await resolveAuthContext(request, {
      allowApiKey: true,
      allowSession: true,
    });

    const body = await request.json();

    // Validate required fields
    if (!body.tenantId) {
      throw new InvalidRequestError('tenantId required');
    }

    if (!body.instanceType) {
      throw new InvalidRequestError('instanceType required');
    }

    if (!body.tier) {
      throw new InvalidRequestError('tier required');
    }

    // Verify tenant access
    const tenant = await prisma.tenant.findUnique({
      where: { id: body.tenantId },
    });

    if (!tenant) {
      return NextResponse.json({ error: 'Tenant not found' }, { status: 404 });
    }

    await ensureTenantAccess(authContext, tenant.orgId, tenant.ownerId, {
      action: 'instance:create',
      tenantId: tenant.id,
      resourceId: tenant.id,
    });

    const createRequest: CreateInstanceRequest = {
      tenantId: body.tenantId,
      instanceType: body.instanceType as InstanceType,
      tierName: body.tier,
      name: body.name,
      region: body.region,
      tags: body.tags,
    };

    const result = await instanceProvisioningService.createInstance(
      createRequest,
      authContext.userId
    );

    return NextResponse.json(result, { status: 201 });
  } catch (error) {
    if (error instanceof ApiError) {
      return NextResponse.json(
        { error: error.message },
        { status: error.statusCode }
      );
    }

    console.error('[API] Error creating instance:', error);
    return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
  }
}
```

Source: `minds-ui/apps/api-service/app/api/v1/instances/route.ts:14`.

### GET [#get]

```typescript
export async function GET(request: NextRequest) {
  try {
    const authContext = await resolveAuthContext(request, {
      allowApiKey: true,
      allowSession: true,
    });

    const url = new URL(request.url);
    const tenantId = url.searchParams.get('tenant_id');

    if (!tenantId) {
      return NextResponse.json({ error: 'tenant_id query parameter required' }, { status: 400 });
    }

    // Verify tenant access
    const tenant = await prisma.tenant.findUnique({
      where: { id: tenantId },
    });

    if (!tenant) {
      return NextResponse.json({ error: 'Tenant not found' }, { status: 404 });
    }

    await ensureTenantAccess(authContext, tenant.orgId, tenant.ownerId, {
      action: 'instance:read',
      tenantId: tenant.id,
      resourceId: tenant.id,
    });

    // Get instances for the tenant
    const instances = await prisma.serviceInstance.findMany({
      where: { tenantId },
      include: {
        serviceType: true,
      },
    });

    return NextResponse.json(instances);
  } catch (error) {
    if (error instanceof ApiError) {
      return NextResponse.json(
        { error: error.message },
        { status: error.statusCode }
      );
    }

    console.error('[API] Error listing instances:', error);
    return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
  }
}
```

Source: `minds-ui/apps/api-service/app/api/v1/instances/route.ts:84`.

## Response and error branches [#response-and-error-branches]

Literal HTTP statuses in the route: 201, 400, 404, 500. Shared management error classes are defined in [Errors and responses](/docs/api/platform/errors).

```typescript
request.json()
```

Source: `minds-ui/apps/api-service/app/api/v1/instances/route.ts:21`.

```typescript
new InvalidRequestError('tenantId required')
```

Source: `minds-ui/apps/api-service/app/api/v1/instances/route.ts:25`.

```typescript
new InvalidRequestError('instanceType required')
```

Source: `minds-ui/apps/api-service/app/api/v1/instances/route.ts:29`.

```typescript
new InvalidRequestError('tier required')
```

Source: `minds-ui/apps/api-service/app/api/v1/instances/route.ts:33`.

```typescript
NextResponse.json({ error: 'Tenant not found' }, { status: 404 })
```

Source: `minds-ui/apps/api-service/app/api/v1/instances/route.ts:42`.

```typescript
NextResponse.json(result, { status: 201 })
```

Source: `minds-ui/apps/api-service/app/api/v1/instances/route.ts:65`.

```typescript
NextResponse.json(
        { error: error.message },
        { status: error.statusCode }
      )
```

Source: `minds-ui/apps/api-service/app/api/v1/instances/route.ts:68`.

```typescript
NextResponse.json({ error: 'Internal server error' }, { status: 500 })
```

Source: `minds-ui/apps/api-service/app/api/v1/instances/route.ts:75`.

```typescript
NextResponse.json({ error: 'tenant_id query parameter required' }, { status: 400 })
```

Source: `minds-ui/apps/api-service/app/api/v1/instances/route.ts:95`.

```typescript
NextResponse.json({ error: 'Tenant not found' }, { status: 404 })
```

Source: `minds-ui/apps/api-service/app/api/v1/instances/route.ts:104`.

```typescript
NextResponse.json(instances)
```

Source: `minds-ui/apps/api-service/app/api/v1/instances/route.ts:121`.

```typescript
NextResponse.json(
        { error: error.message },
        { status: error.statusCode }
      )
```

Source: `minds-ui/apps/api-service/app/api/v1/instances/route.ts:124`.

```typescript
NextResponse.json({ error: 'Internal server error' }, { status: 500 })
```

Source: `minds-ui/apps/api-service/app/api/v1/instances/route.ts:131`.

## Service dependencies [#service-dependencies]

* `minds-ui/apps/api-service/lib/services/auth-context.ts`
* `minds-ui/apps/api-service/lib/services/instance-provisioning-service.ts`
* `minds-ui/apps/api-service/types/errors.ts`
* `minds-ui/apps/api-service/lib/db.ts`

## Evidence [#evidence]

Generated from the local source snapshot on 2026-09-12. This page documents implemented code and does not certify a deployed service, permissions configuration, or successful provider operation.

Source file: `minds-ui/apps/api-service/app/api/v1/instances/route.ts`. SHA-256: `800e96ec9a25ee72ee02f89e0a24d4dfb5b2f3bdf5425feb2aca5a612fd14fb3`.
