Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
encoredev avatar

Encore Go Api

  • 394 installs
  • 26 repo stars
  • Updated May 15, 2026
  • encoredev/skills

encore-go-api is an agent skill that teaches typed Encore Go REST endpoint patterns with //encore:api annotations, parameter binding, validation, and APIError handling for production services.

About

encore-go-api is an Encore.dev agent skill that standardizes how developers declare HTTP APIs in Go using the //encore:api annotation. It covers public, private, and auth visibility flags plus GET, POST, PUT, PATCH, and DELETE methods with :param path placeholders. Request data binds from path, query, header, and JSON body fields via struct tags, while responses use pointer-to-struct types or omit bodies when empty. The skill documents sensitive endpoint redaction, custom HTTP status via encore:"httpstatus" tags, raw handlers for webhooks, and encore.dev/beta/errs error codes. Developers reach for encore-go-api when scaffolding Encore microservices, authenticated routes, or paginated list endpoints without hand-writing router boilerplate. It pairs with other Encore skills for databases and auth handlers on the same service.

  • //encore:api annotations with public/private access and HTTP methods
  • Typed request/response structs with path, query, header, and cookie params
  • errs.NotFound and 4xx–5xx error return patterns
  • Explicit split: raw endpoints and inbound webhooks use encore-go-webhook skill instead

Encore Go Api by the numbers

  • 394 all-time installs (skills.sh)
  • Ranked #1,097 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
  • Data as of Jul 24, 2026 (Skillselion catalog sync)
npx skills add https://github.com/encoredev/skills --skill encore-go-api

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs394
repo stars26
Last updatedMay 15, 2026
Repositoryencoredev/skills

How do you define typed REST APIs in Encore Go?

Define typed Encore Go REST endpoints with correct annotations, params, validation, and error returns while you build your backend service.

Who is it for?

Go developers building Encore microservices who need consistent //encore:api endpoint patterns with auth and validation.

Skip if: Teams using Encore TypeScript, plain net/http without Encore, or projects only needing database migrations without new routes.

When should I use this skill?

The user defines an Encore Go endpoint, mentions //encore:api, or asks for typed path, query, and header binding in Encore.

What you get

Annotated Go handler functions with typed request/response structs, route paths, and consistent HTTP error mapping.

  • annotated API handler functions
  • typed request/response structs
  • errs-based error responses

By the numbers

  • Documents 5 HTTP methods: GET, POST, PUT, PATCH, DELETE
  • Covers 3 visibility modes: public, private, and auth

Files

SKILL.mdMarkdownGitHub ↗

Encore API Endpoints

Instructions

When creating API endpoints with Encore.ts, follow these patterns:

1. Import the API module

import { api } from "encore.dev/api";

2. Define typed request/response interfaces

Always define explicit TypeScript interfaces for request and response types:

interface CreateUserRequest {
  email: string;
  name: string;
}

interface CreateUserResponse {
  id: string;
  email: string;
  name: string;
}

3. Create the endpoint

export const createUser = api(
  { method: "POST", path: "/users", expose: true },
  async (req: CreateUserRequest): Promise<CreateUserResponse> => {
    // Implementation
  }
);

API Options

OptionTypeDescription
methodstringHTTP method: GET, POST, PUT, PATCH, DELETE
pathstringURL path, supports :param and *wildcard
exposebooleanIf true, accessible from outside (default: false)
authbooleanIf true, requires authentication
sensitivebooleanIf true, redacts request/response payloads from traces

Request/Response Patterns

Encore supports four endpoint configurations:

// Both request and response
export const createUser = api(
  { method: "POST", path: "/users", expose: true },
  async (req: CreateRequest): Promise<CreateResponse> => { ... }
);

// Response only (no request body)
export const listUsers = api(
  { method: "GET", path: "/users", expose: true },
  async (): Promise<ListResponse> => { ... }
);

// Request only (no response body)
export const deleteUser = api(
  { method: "DELETE", path: "/users/:id", expose: true },
  async (req: DeleteRequest): Promise<void> => { ... }
);

// Neither request nor response
export const ping = api(
  { method: "GET", path: "/ping", expose: true },
  async (): Promise<void> => { ... }
);

Custom HTTP Status Codes

Include an HttpStatus field in your response to return custom status codes:

import { api, HttpStatus } from "encore.dev/api";

interface CreateResponse {
  id: string;
  status: HttpStatus;
}

export const create = api(
  { method: "POST", path: "/items", expose: true },
  async (req: CreateRequest): Promise<CreateResponse> => {
    const item = await createItem(req);
    return { id: item.id, status: HttpStatus.Created };  // Returns 201
  }
);

Parameter Types

Path Parameters

// Path: "/users/:id"
interface GetUserRequest {
  id: string;  // Automatically mapped from :id
}

Query Parameters

import { Query } from "encore.dev/api";

interface ListUsersRequest {
  limit?: Query<number>;
  offset?: Query<number>;
}

Headers

import { Header } from "encore.dev/api";

interface WebhookRequest {
  signature: Header<"X-Webhook-Signature">;
  payload: string;
}

Cookies

import { Cookie } from "encore.dev/api";

interface SessionRequest {
  session?: Cookie<"session">;
  settings?: Cookie<"user-settings">;
}

Request Validation

Encore validates requests at runtime using TypeScript types. Add constraints for stricter validation:

import { api } from "encore.dev/api";
import { Min, Max, MinLen, MaxLen, IsEmail, IsURL } from "encore.dev/validate";

interface CreateUserRequest {
  email: string & IsEmail;                    // Must be valid email
  username: string & MinLen<3> & MaxLen<20>;  // 3-20 characters
  age: number & Min<13> & Max<120>;           // Between 13 and 120
  website?: string & IsURL;                   // Optional, must be URL if provided
}

Combining Validation Rules

Use & for AND logic (must pass all rules) and | for OR logic (must pass at least one):

import { IsEmail, IsURL, MinLen, MaxLen } from "encore.dev/validate";

interface ContactRequest {
  // Must be valid email OR valid URL
  contact: string & (IsEmail | IsURL);
  // Must be 5-100 chars AND be a valid URL
  website: string & MinLen<5> & MaxLen<100> & IsURL;
}

Available Validators

ValidatorApplies ToExample
Min<N>numberage: number & Min<18>
Max<N>numbercount: number & Max<100>
MinLen<N>string, arrayname: string & MinLen<1>
MaxLen<N>string, arraytags: string[] & MaxLen<10>
IsEmailstringemail: string & IsEmail
IsURLstringlink: string & IsURL
StartsWith<S>stringid: string & StartsWith<"usr_">
EndsWith<S>stringfile: string & EndsWith<".json">
MatchesRegexp<R>stringcode: string & MatchesRegexp<"^[A-Z]{3}$">

Validation Error Response

Invalid requests return 400 with details:

{
  "code": "invalid_argument",
  "message": "validation failed",
  "details": { "field": "email", "error": "must be a valid email" }
}

Error Handling

Use APIError for proper HTTP error responses:

import { APIError, ErrCode } from "encore.dev/api";

// Throw with error code
throw new APIError(ErrCode.NotFound, "user not found");

// Or use shorthand
throw APIError.notFound("user not found");
throw APIError.invalidArgument("email is required");
throw APIError.unauthenticated("invalid token");

Common Error Codes

CodeHTTP StatusUsage
NotFound404Resource doesn't exist
InvalidArgument400Bad input
Unauthenticated401Missing/invalid auth
PermissionDenied403Not allowed
AlreadyExists409Duplicate resource

Static Assets

Serve static files (HTML, CSS, JS, images) with api.static:

import { api } from "encore.dev/api";

// Serve files from ./assets under /static/*
export const assets = api.static(
  { expose: true, path: "/static/*path", dir: "./assets" }
);

// Serve at root (use !path for fallback routing)
export const frontend = api.static(
  { expose: true, path: "/!path", dir: "./dist" }
);

// Custom 404 page
export const app = api.static(
  { expose: true, path: "/!path", dir: "./public", notFound: "./404.html" }
);

Path Syntax

  • *path - Standard wildcard: matches all paths under the prefix (e.g., /static/*path)
  • !path - Fallback routing: serves static files at domain root without conflicting with other API endpoints. Use this for SPAs where unmatched routes should serve index.html

Guidelines

  • Always use import not require
  • Define explicit interfaces for type safety
  • Use expose: true only for public endpoints
  • Throw APIError instead of returning error objects
  • For inbound webhooks (Stripe, GitHub, etc.) use api.raw — see the encore-webhook skill
  • Path parameters are automatically extracted from the path pattern
  • Use validation constraints (Min, MaxLen, etc.) for user input

Related skills

How it compares

Use encore-go-api for Encore-native annotated handlers; use encore-webhook when raw inbound webhook parsing is the primary task.

FAQ

What annotation does encore-go-api use to expose Go functions as HTTP endpoints?

encore-go-api places //encore:api immediately above handler functions with options like public, private, auth, method=GET, and path=/users/:id so Encore generates the HTTP surface and binding automatically.

How should request and response types be declared in Encore Go APIs?

encore-go-api requires request parameters as a pointer to a struct or omitted entirely, responses as a pointer to a struct or omitted for no body, and error as the final return value using encore.dev/beta/errs.

When does encore-go-api recommend raw endpoints?

encore-go-api directs developers to raw handlers via api.raw() when they need low-level HTTP access for inbound webhooks or custom headers outside the standard typed JSON request/response pattern.

Backend & APIsbackendintegrations

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.