Skip to content
Written with Claude

INTERNAL

Also known as

internal, internal_only (with or without @ prefix)

Mark an endpoint as internal-only — accessible via self-referencing calls (proxy annotations and HTTP client types with relative paths) but not exposed as a public HTTP route.

Direct HTTP calls to an internal endpoint return 404. Internal calls via proxy or HTTP client types work normally.

Syntax

code
@internal
@internal_only
internal
internal_only

All forms are equivalent.

Example: Internal Helper with Proxy

sql
sql
-- Internal helper: returns data but is NOT callable from outside
create function get_cached_rates()
returns json language sql as $$
    select rates from exchange_rates order by fetched_at desc limit 1
$$;
comment on function get_cached_rates() is 'HTTP GET
@internal';

-- Public endpoint that proxies the internal one
create function convert_currency(_amount numeric, _from text, _to text)
returns json language plpgsql as $$
...
$$;
comment on function convert_currency(numeric, text, text) is 'HTTP GET
proxy GET /api/get-cached-rates';
  • GET /api/get-cached-rates404 Not Found
  • GET /api/convert-currency?amount=100&from=USD&to=EUR → works (proxies internally)

Example: Internal Helper with HTTP Client Types

sql
sql
-- Internal data source
create function get_users()
returns json language sql as $$
    select json_agg(row_to_json(u)) from users u
$$;
comment on function get_users() is 'HTTP GET
@internal';

-- HTTP client type pointing to internal endpoint
create type api_users as (body text);
comment on type api_users is 'GET /api/get-users';

-- Public endpoint composing internal calls
create function get_dashboard(_users api_users)
returns json language plpgsql as $$
begin
    return json_build_object('users', (_users).body::json);
end;
$$;

SQL File Endpoints

Works on all endpoint sources — functions, procedures, and SQL files:

sql
sql
-- sql/internal_helper.sql
-- HTTP GET
-- @internal
select * from cached_data;

Comments