Use audiences to filter your API

Use x-fern-audiences to filter to relevant services, methods and messages

Audiences are a useful tool for segmenting your gRPC API for different consumers. Common examples of audiences include public and beta.

Remember to filter your SDKs and Docs after specifying audiences. If no audiences are specified, nothing will be filtered.

The following example configures the SDK to filter to the public audience:

generators.yml
1groups:
2 sdks:
3 audiences:
4 - public
5 generators:
6 - name: fernapi/fern-typescript-node-sdk
7 version: 0.8.8

The following example configures the docs to filter to the public audience:

docs.yml
1navigation:
2 - api: API Reference
3 audiences:
4 - public

Filter services

Add x-fern-audiences to services to control which services are included for specific audiences:

user_service.proto
1syntax = "proto3";
2
3package userservice.v1;
4
5// Public user service available to all clients
6service UserService {
7 option (x_fern_audiences) = "public";
8
9 rpc GetUser(GetUserRequest) returns (User);
10 rpc CreateUser(CreateUserRequest) returns (User);
11}
12
13// Internal admin service for administrative operations
14service AdminService {
15 option (x_fern_audiences) = "admin";
16
17 rpc ListAllUsers(ListAllUsersRequest) returns (ListAllUsersResponse);
18 rpc DeleteUser(DeleteUserRequest) returns (google.protobuf.Empty);
19 rpc BanUser(BanUserRequest) returns (google.protobuf.Empty);
20}

Filter individual methods

You can filter specific methods within services:

mixed_service.proto
1syntax = "proto3";
2
3package userservice.v1;
4
5service UserService {
6 // Public method available to all
7 rpc GetUser(GetUserRequest) returns (User) {
8 option (x_fern_audiences) = "public";
9 }
10
11 // Beta method only for beta testers
12 rpc GetUserAnalytics(GetUserAnalyticsRequest) returns (UserAnalytics) {
13 option (x_fern_audiences) = "beta";
14 }
15
16 // Internal method for debugging
17 rpc GetUserDebugInfo(GetUserDebugRequest) returns (UserDebugInfo) {
18 option (x_fern_audiences) = "internal";
19 }
20}

Filter message fields

Filter specific fields within message types:

user_messages.proto
1syntax = "proto3";
2
3package userservice.v1;
4
5message User {
6 string id = 1; // Available to all audiences
7 string email = 2; // Available to all audiences
8 string name = 3; // Available to all audiences
9
10 // Admin-only fields
11 string internal_id = 4 [(x_fern_audiences) = "admin"];
12 repeated string permissions = 5 [(x_fern_audiences) = "admin"];
13 google.protobuf.Timestamp created_at = 6 [(x_fern_audiences) = "admin"];
14
15 // Debug-only fields
16 map<string, string> debug_metadata = 7 [(x_fern_audiences) = "debug"];
17 string session_id = 8 [(x_fern_audiences) = "debug"];
18}

Filter entire messages

Filter entire message types to different audiences:

filtered_messages.proto
1syntax = "proto3";
2
3package userservice.v1;
4
5// Public user data
6message PublicUser {
7 option (x_fern_audiences) = "public";
8
9 string id = 1;
10 string name = 2;
11 string avatar_url = 3;
12}
13
14// Extended user data for authenticated users
15message AuthenticatedUser {
16 option (x_fern_audiences) = "authenticated";
17
18 string id = 1;
19 string name = 2;
20 string email = 3;
21 string phone = 4;
22 UserPreferences preferences = 5;
23}
24
25// Full user data for administrators
26message AdminUser {
27 option (x_fern_audiences) = "admin";
28
29 string id = 1;
30 string name = 2;
31 string email = 3;
32 string phone = 4;
33 UserPreferences preferences = 5;
34 repeated string roles = 6;
35 repeated Permission permissions = 7;
36 google.protobuf.Timestamp created_at = 8;
37 google.protobuf.Timestamp last_login = 9;
38 string created_by = 10;
39}

Filter enums and enum values

Filter enum values based on audience:

user_enums.proto
1syntax = "proto3";
2
3package userservice.v1;
4
5enum UserStatus {
6 USER_STATUS_UNSPECIFIED = 0;
7
8 // Public statuses
9 USER_STATUS_ACTIVE = 1 [(x_fern_audiences) = "public"];
10 USER_STATUS_INACTIVE = 2 [(x_fern_audiences) = "public"];
11
12 // Admin-only statuses
13 USER_STATUS_SUSPENDED = 3 [(x_fern_audiences) = "admin"];
14 USER_STATUS_BANNED = 4 [(x_fern_audiences) = "admin"];
15 USER_STATUS_PENDING_VERIFICATION = 5 [(x_fern_audiences) = "admin"];
16
17 // Internal debugging statuses
18 USER_STATUS_DEBUG = 6 [(x_fern_audiences) = "debug"];
19 USER_STATUS_TEST = 7 [(x_fern_audiences) = "debug"];
20}
21
22enum OperationType {
23 OPERATION_TYPE_UNSPECIFIED = 0;
24
25 // Available to beta users
26 OPERATION_TYPE_EXPERIMENTAL_FEATURE = 1 [(x_fern_audiences) = "beta"];
27 OPERATION_TYPE_ADVANCED_ANALYTICS = 2 [(x_fern_audiences) = "beta"];
28
29 // Internal operations
30 OPERATION_TYPE_SYSTEM_MAINTENANCE = 3 [(x_fern_audiences) = "internal"];
31}

Request/Response filtering

Filter request and response messages based on audience:

request_response.proto
1syntax = "proto3";
2
3package userservice.v1;
4
5service UserService {
6 // Method with different request/response based on audience
7 rpc GetUserProfile(GetUserProfileRequest) returns (GetUserProfileResponse);
8}
9
10message GetUserProfileRequest {
11 string user_id = 1;
12
13 // Admin can request additional data
14 bool include_internal_data = 2 [(x_fern_audiences) = "admin"];
15 bool include_audit_log = 3 [(x_fern_audiences) = "admin"];
16
17 // Debug fields
18 bool include_debug_info = 4 [(x_fern_audiences) = "debug"];
19}
20
21message GetUserProfileResponse {
22 PublicUserProfile public_profile = 1; // Always included
23
24 AdminUserProfile admin_profile = 2 [(x_fern_audiences) = "admin"]; // Admin only
25 repeated AuditLogEntry audit_log = 3 [(x_fern_audiences) = "admin"]; // Admin only
26
27 DebugInfo debug_info = 4 [(x_fern_audiences) = "debug"]; // Debug only
28}

Conditional method definitions

Use audiences to expose different versions of methods:

conditional_methods.proto
1syntax = "proto3";
2
3package userservice.v1;
4
5service UserService {
6 // Basic user creation for public
7 rpc CreateUser(CreateUserRequest) returns (User) {
8 option (x_fern_audiences) = "public";
9 }
10
11 // Enhanced user creation for admin
12 rpc CreateUserWithPermissions(CreateUserWithPermissionsRequest) returns (AdminUser) {
13 option (x_fern_audiences) = "admin";
14 }
15
16 // Bulk user creation for enterprise
17 rpc BulkCreateUsers(BulkCreateUsersRequest) returns (BulkCreateUsersResponse) {
18 option (x_fern_audiences) = "enterprise";
19 }
20
21 // Beta features
22 rpc CreateUserWithAI(CreateUserWithAIRequest) returns (User) {
23 option (x_fern_audiences) = "beta";
24 }
25}

Streaming method filtering

Filter streaming methods by audience:

streaming_methods.proto
1syntax = "proto3";
2
3package userservice.v1;
4
5service UserStreamingService {
6 // Public event streaming
7 rpc StreamUserEvents(StreamUserEventsRequest) returns (stream PublicUserEvent) {
8 option (x_fern_audiences) = "public";
9 }
10
11 // Admin event streaming with more details
12 rpc StreamAdminEvents(StreamAdminEventsRequest) returns (stream AdminEvent) {
13 option (x_fern_audiences) = "admin";
14 }
15
16 // Internal debugging stream
17 rpc StreamDebugEvents(StreamDebugEventsRequest) returns (stream DebugEvent) {
18 option (x_fern_audiences) = "debug";
19 }
20}

Multiple audience support

Assign multiple audiences to services or methods:

multiple_audiences.proto
1syntax = "proto3";
2
3package userservice.v1;
4
5service UserService {
6 // Available to both public and authenticated users
7 rpc GetPublicUserInfo(GetPublicUserInfoRequest) returns (PublicUserInfo) {
8 option (x_fern_audiences) = "public,authenticated";
9 }
10
11 // Available to admin and support staff
12 rpc GetUserSupportInfo(GetUserSupportInfoRequest) returns (UserSupportInfo) {
13 option (x_fern_audiences) = "admin,support";
14 }
15
16 // Available to beta and internal users
17 rpc TestNewFeature(TestNewFeatureRequest) returns (TestNewFeatureResponse) {
18 option (x_fern_audiences) = "beta,internal";
19 }
20}

Using custom extensions

Define custom Fern extensions for audience filtering:

custom_extensions.proto
1syntax = "proto3";
2
3package userservice.v1;
4
5import "google/protobuf/descriptor.proto";
6
7// Define custom option for audience filtering
8extend google.protobuf.ServiceOptions {
9 string x_fern_audiences = 50001;
10}
11
12extend google.protobuf.MethodOptions {
13 string x_fern_audiences = 50002;
14}
15
16extend google.protobuf.FieldOptions {
17 string x_fern_audiences = 50003;
18}
19
20extend google.protobuf.MessageOptions {
21 string x_fern_audiences = 50004;
22}
23
24extend google.protobuf.EnumValueOptions {
25 string x_fern_audiences = 50005;
26}

This allows you to create different views of the same gRPC API for different types of consumers, ensuring each audience only sees the services, methods, and data relevant to their use case.