All skills
lukemurraynz avatar

/typespec-api-design

@2cc2455

Design new API-first, contract-first contracts with TypeSpec, OpenAPI/swagger output, Azure data-plane and ARM patterns, versioning, pagination, LROs, CI validation, and agent-ready API boundaries. WHEN: create API spec, API-first design, contract-first, scaffold TypeSpec project, generate OpenAPI or swagger, define REST contract, add API versioning, define LRO, migrate OpenAPI to TypeSpec, Azure API review, SpecKit API.

Use this Skill: https://skilld.dev/gh/lukemurraynz/hve-agent-skills/typespec-api-design

This session only. Nothing lands on disk.

bundlesazure-armguide.md

≈1.8k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Azure Resource Manager API bundle

Use this bundle only for ARM resource provider APIs. ARM contracts are not generic REST APIs; they require ARM-specific routing, resource identity, provider namespace, operations, and lifecycle semantics.

Recommended dependencies

{
  "type": "module",
  "private": true,
  "scripts": {
    "build": "tsp compile . --warn-as-error",
    "watch": "tsp compile . --watch",
    "format": "tsp format \"**/*.tsp\""
  },
  "dependencies": {
    "@typespec/compiler": "<verified-compatible-version>",
    "@typespec/http": "<verified-compatible-version>",
    "@typespec/rest": "<verified-compatible-version>",
    "@typespec/versioning": "<verified-compatible-version>",
    "@azure-tools/typespec-azure-core": "<verified-compatible-version>",
    "@azure-tools/typespec-azure-resource-manager": "<verified-compatible-version>",
    "@azure-tools/typespec-autorest": "<verified-compatible-version>"
  }
}

Recommended start

Prefer the official Azure template for new ARM work:

npx tsp init https://aka.ms/typespec/azure-init
# Select the Azure Resource Manager service project template
npm install
npx tsp compile . --warn-as-error

Tracked resource example

import "@azure-tools/typespec-azure-resource-manager";

using Azure.ResourceManager;

@armProviderNamespace
@service(#{ title: "Microsoft.Contoso" })
@versioned(Versions)
namespace Microsoft.Contoso;

enum Versions { v2026_05_01: "2026-05-01" }

model Widget is TrackedResource<WidgetProperties> {
  @key("widgetName") @segment("widgets")
  @path @maxLength(63) @pattern("^[a-z0-9-]+$")
  name: string;
}

model WidgetProperties {
  @visibility(Lifecycle.Read) provisioningState?: ResourceProvisioningState;
  displayName: string;
}

@armResourceOperations
interface Widgets {
  get is ArmResourceRead<Widget>;
  createOrUpdate is ArmResourceCreateOrReplaceAsync<Widget>;
  update is ArmResourcePatchAsync<Widget, WidgetProperties>;
  delete is ArmResourceDeleteWithoutOkAsync<Widget>;
  listByResourceGroup is ArmResourceListByParent<Widget>;
  listBySubscription is ArmListBySubscription<Widget>;
}

provisioningState enum

ARM mandates only the three terminal provisioning-state values - Succeeded, Failed, Canceled - which the ResourceProvisioningState type from Azure.ResourceManager provides. Resource providers almost always also expose non-terminal states (commonly Creating, Updating, Deleting, Accepted); these are RP-defined and recommended, not required by ARM. Add the non-terminal states your RP uses as a union over ResourceProvisioningState:

union WidgetProvisioningState {
  ResourceProvisioningState,
  "Creating",
  "Updating",
  "Deleting",
  "Accepted",
}

Operations API

Every ARM resource provider MUST expose a Microsoft.<RP>/operations endpoint that lists the RP's operations. Use the standard template:

interface Operations extends Azure.ResourceManager.Operations {}

Proxy and Extension resources

  • model ChildThing is ProxyResource<ChildThingProperties> - for child resources that don't have their own location/tags (e.g., per-region configuration under a tracked parent).
  • model Permission is ExtensionResource<PermissionProperties> - for resources that attach to an existing resource of another type (e.g., role assignments, locks, diagnostics settings).

Locations

Never hard-code Azure region enums in a TypeSpec contract - Azure adds new regions continuously, and a frozen enum becomes a contract bug the day a customer deploys to a new region. ARM expects @armResourceIdentifier on cross-resource references and runtime location validation by the RP, not contract-time enumeration.

Common ARM rejections

Reviewer-killers seen repeatedly in Azure API review:

  • Missing systemData on the resource. TrackedResource and ProxyResource templates auto-include it - verify it appears in emitted OpenAPI output.
  • Missing @armProviderNamespace decorator on the namespace.
  • PUT operation missing the 201 Created response. Use the *Async operation templates (ArmResourceCreateOrReplaceAsync) rather than hand-rolled ops.
  • Properties hoisted to the resource root instead of nested inside the properties: {} envelope. ARM mandates the envelope shape.
  • Required properties added in a non-breaking version. For ARM this is ALWAYS breaking, even if the property is on a response - bump the API version.

ARM design rules

  • Use @azure-tools/typespec-azure-resource-manager patterns and templates.
  • Provider namespace, resource types, scope, and API versions must be explicit.
  • ARM resources need name, type, id, systemData, tags, location where applicable, and standard provisioning state semantics.
  • Avoid inventing custom control-plane patterns when ARM templates already exist.
  • Do not use deprecated location patterns for new work; prefer current ARM location-scoped resource patterns from the Azure TypeSpec docs.
  • Generated Swagger/AutoRest output may need to be checked in if the Azure SDK/API review pipeline requires it; otherwise treat it as an artifact.

ARM-specific gotchas

  • Resource type names use PascalCase singular in TypeSpec models (e.g. VirtualMachine) but appear as lowercase plural URL segments (virtualMachines). This pluralization is controlled by the resource template - do not hand-route it.
  • @parentResource is required on nested resources; without it the emitter generates malformed routes that miss the parent segment.
  • Tracked resources require location, tags, and systemData. The Azure Core / ARM templates wire these in for you - do not redeclare them.
  • The default API version for ARM is the latest GA. Preview versions live under the azure-rest-api-specs preview folder, not the GA folder.
  • The azure-rest-api-specs repo requires both stable/<version>/ and preview/<version>/ folder placement for resources that ship in both channels. Confirm both folders are correct before opening a PR.

@parentResource caveat

@parentResource is silently ignored when used with Azure.Core.Legacy.* operation templates, producing flat routes that miss the parent path segment. Use the modern ARM/Core resource templates (ArmResource*, Operations.Resource*) which honor parent resources correctly. Verify this behavior against your pinned library versions before relying on either pattern - the Legacy templates exist only for migration and their quirks are fixed by design.

ARM review checks

  • Provider namespace is correct and stable.
  • Resource names use ARM-compatible constraints.
  • Resource hierarchy and scope are correct: tenant, management group, subscription, resource group, extension, or location-scoped.
  • Long-running create/update/delete operations follow ARM LRO rules.
  • api-version is present and governed by TypeSpec versioning.
  • Common ARM operations are present where expected: get, create/update, delete, list by parent/scope, provider operations.
  • Examples are complete and match emitted swagger.
  • RP registration, permissions, and RBAC implications are documented outside the TypeSpec contract if relevant.

Source: SKILL.md on GitHub

No alerts8d3 checks · Risk SAFE
  • Gen Agent Trust Hub8d

    This skill is a comprehensive and legitimate tool for designing API-first contracts using TypeSpec and Azure patterns. It includes extensive security best practices, particularly regarding SSRF defense, PII handling, and idempotency. The only detected concern is a standard vulnerability surface for indirect prompt injection when processing external OpenAPI specifications for migration.

  • Socket8d

    No alerts

  • Snyk8d

    Risk: LOW · No issues

Signed by skilld at 2cc2455. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last month.

Steadyupdated last month
metadata
{
  "last_verified": "2026-08-26",
  "version": "1.3.1"
}

README badge

README badge for lukemurraynz/hve-agent-skills/typespec-api-design