Create a schema for a topic Stay organized with collections Save and categorize content based on your preferences.
This document shows you how to create schemas for Pub/Sub topics.
Before you begin
Before you create a schema, complete the following:
- Learn abouttopics and the publishing workflow.
- Understand howPub/Sub schemas work.
- Create a topic.
Required roles and permissions
To get the permissions that you need to create and manage schemas, ask your administrator to grant you thePub/Sub Editor (roles/pubsub.editor) IAM role on your project. For more information about granting roles, seeManage access to projects, folders, and organizations.
This predefined role contains the permissions required to create and manage schemas. To see the exact permissions that are required, expand theRequired permissions section:
Required permissions
The following permissions are required to create and manage schemas:
- Create schema:
pubsub.schemas.create - Attach schema to topic:
pubsub.schemas.attach - Commit a schema revision:
pubsub.schemas.commit - Delete a schema or a schema revision:
pubsub.schemas.delete - Get a schema or schema revisions:
pubsub.schemas.get - List schemas:
pubsub.schemas.list - List schema revisions:
pubsub.schemas.listRevisions - Rollback a schema:
pubsub.schemas.rollback - Validate a message:
pubsub.schemas.validate - Get the IAM policy for a schema:
pubsub.schemas.getIamPolicy - Configure theIAM policy for a schema:
pubsub.schemas.setIamPolicy
You might also be able to get these permissions withcustom roles or otherpredefined roles.
You can grant roles and permissions to principals such as users, groups,domains, or service accounts. You can create a schema in one project andattach it to a topic located in a different project.Ensure that you have the required permissions foreach project.
Create a schema
You can create a schema using the Google Cloud console, the gcloud CLI,the Pub/Sub API, or the Cloud Client Libraries.
Before creating a schema, review thisimportant information about schemas.
Console
To create a schema, follow these steps:
In the Google Cloud console, go to thePub/Sub schemas page.
ClickCreate schema.
In theSchema ID field, enter an ID for your schema.
For guidelines to name a schema, seeGuidelines to name a topic, subscription, or snapshot.
ForSchema type, select either Avro or Protocol Buffer.
Learn more aboutschema types.
In theSchema definition field, enter the Avro or Protocol Bufferdefinition for your schema.
For example, here's a sample schema in Avro.
{"type":"record","name":"Avro","fields":[{"name":"ProductName","type":"string","default":""},{"name":"SKU","type":"int","default":0},{"name":"InStock","type":"boolean","default":false}]}Optional: ClickValidate definition to check if the schema definitionis correct.
The validation check does not check the compatibility of the schema withthe messages to be published. Test messages in the next step.
Optional: You can test if messages with the correct schema get published.
ClickTest message.
In theTest message window, select a type ofMessage encoding.
In theMessage body, enter a test message.
ClickTest.
For example, here's a sample message for the test schema.In this example, select theMessage encoding as
JSON.{"ProductName":"GreenOnions","SKU":34543,"InStock":true}Exit the test message page.
ClickCreate to save the schema.
gcloud
gcloudpubsubschemascreateSCHEMA_ID\--type=SCHEMA_TYPE\--definition=SCHEMA_DEFINITION
Where:
- SCHEMA_TYPE is either
avroorprotocol-buffer. - SCHEMA_DEFINITION is a
stringcontaining the definition ofthe schema, formatted according to the chosenschema type.
You can also specify the schema definition in a file:
gcloudpubsubschemascreateSCHEMA_ID\--type=SCHEMA_TYPE\--definition-file=SCHEMA_DEFINITION_FILE
Where:
- SCHEMA_TYPE is either
avroorprotocol-buffer. - SCHEMA_DEFINITION_FILE is a
stringcontaining the path to thefile with the definition of the schema, formatted according to the chosenschema type.
REST
To create a schema, send a POST request like the following:
POST https://pubsub.googleapis.com/v1/projects/PROJECT_ID/schemas?schemaId=SCHEMA_IDAuthorization: Bearer $(gcloud auth application-default print-access-token)Content-Type: application/json --data @response-body.json
Specify the following fields in the request body:
{"definition":SCHEMA_DEFINITION"type":SCHEMA_TYPE}
Where:
- SCHEMA_TYPE is either
avroorprotocol-buffer. - SCHEMA_DEFINITION is a string containing the definition ofthe schema, formatted according to the chosenschema type.
The response body should contain a JSON representation of aschema resource.For example:
{ "name":SCHEMA_NAME, "type":SCHEMA_TYPE, "definition":SCHEMA_DEFINITION "revisionId":REVISION_ID "revisionCreateTime":REVISION_CREATE_TIME}Where:
- REVISION_ID is the server-generated ID for the revision.
- REVISION_CREATE_TIME is the ISO 8601 timestamp at which therevision was created.
C++
Before trying this sample, follow the C++ setup instructions inQuickstart: Using Client Libraries. For more information, see thePub/Sub C++ API reference documentation.
Avro
namespacepubsub=::google::cloud::pubsub;[](pubsub::SchemaServiceClientclient,std::stringconst&project_id,std::stringconst&schema_id,std::stringconst&schema_definition_file){std::stringconstdefinition=ReadFile(schema_definition_file);google::pubsub::v1::CreateSchemaRequestrequest;request.set_parent(google::cloud::Project(project_id).FullName());request.set_schema_id(schema_id);request.mutable_schema()->set_type(google::pubsub::v1::Schema::AVRO);request.mutable_schema()->set_definition(definition);autoschema=client.CreateSchema(request);if(schema.status().code()==google::cloud::StatusCode::kAlreadyExists){std::cout <<"The schema already exists\n";return;}if(!schema)throwstd::move(schema).status();std::cout <<"Schema successfully created: " <<schema->DebugString() <<"\n";}Proto
namespacepubsub=::google::cloud::pubsub;[](pubsub::SchemaServiceClientclient,std::stringconst&project_id,std::stringconst&schema_id,std::stringconst&schema_definition_file){std::stringconstdefinition=ReadFile(schema_definition_file);google::pubsub::v1::CreateSchemaRequestrequest;request.set_parent(google::cloud::Project(project_id).FullName());request.set_schema_id(schema_id);request.mutable_schema()->set_type(google::pubsub::v1::Schema::PROTOCOL_BUFFER);request.mutable_schema()->set_definition(definition);autoschema=client.CreateSchema(request);if(schema.status().code()==google::cloud::StatusCode::kAlreadyExists){std::cout <<"The schema already exists\n";return;}if(!schema)throwstd::move(schema).status();std::cout <<"Schema successfully created: " <<schema->DebugString() <<"\n";}C#
Before trying this sample, follow the C# setup instructions inQuickstart: Using Client Libraries. For more information, see thePub/Sub C# API reference documentation.
Avro
usingGoogle.Api.Gax.ResourceNames;usingGoogle.Cloud.PubSub.V1;usingGrpc.Core;usingSystem;usingSystem.IO;publicclassCreateAvroSchemaSample{publicSchemaCreateAvroSchema(stringprojectId,stringschemaId,stringpathToDefinition){SchemaServiceClientschemaService=SchemaServiceClient.Create();varschemaName=SchemaName.FromProjectSchema(projectId,schemaId);stringschemaDefinition=File.ReadAllText(pathToDefinition);Schemaschema=newSchema{SchemaName=schemaName,Type=Schema.Types.Type.Avro,Definition=schemaDefinition};CreateSchemaRequestcreateSchemaRequest=newCreateSchemaRequest{ParentAsProjectName=ProjectName.FromProject(projectId),SchemaId=schemaId,Schema=schema};try{schema=schemaService.CreateSchema(createSchemaRequest);Console.WriteLine($"Schema {schema.Name} created.");}catch(RpcExceptione)when(e.Status.StatusCode==StatusCode.AlreadyExists){Console.WriteLine($"Schema {schemaName} already exists.");}returnschema;}}Proto
usingGoogle.Api.Gax.ResourceNames;usingGoogle.Cloud.PubSub.V1;usingGrpc.Core;usingSystem;usingSystem.IO;publicclassCreateProtoSchemaSample{publicSchemaCreateProtoSchema(stringprojectId,stringschemaId,stringpathToDefinition){SchemaServiceClientschemaService=SchemaServiceClient.Create();varschemaName=SchemaName.FromProjectSchema(projectId,schemaId);stringschemaDefinition=File.ReadAllText(pathToDefinition);Schemaschema=newSchema{SchemaName=schemaName,Type=Schema.Types.Type.ProtocolBuffer,Definition=schemaDefinition};CreateSchemaRequestcreateSchemaRequest=newCreateSchemaRequest{ParentAsProjectName=ProjectName.FromProject(projectId),SchemaId=schemaId,Schema=schema};try{schema=schemaService.CreateSchema(createSchemaRequest);Console.WriteLine($"Schema {schema.Name} created.");}catch(RpcExceptione)when(e.Status.StatusCode==StatusCode.AlreadyExists){Console.WriteLine($"Schema {schemaName} already exists.");}returnschema;}}Go
The following sample uses the major version of the Go Pub/Sub client library (v2). If you are still using the v1 library, seethe migration guide to v2.To see a list of v1 code samples, seethe deprecated code samples.
Before trying this sample, follow the Go setup instructions inQuickstart: Using Client Libraries.For more information, see thePub/Sub Go API reference documentation.
Avro
import("context""fmt""io""os"pubsub"cloud.google.com/go/pubsub/v2/apiv1""cloud.google.com/go/pubsub/v2/apiv1/pubsubpb")// createAvroSchema creates a schema resource from a JSON-formatted Avro schema file.funccreateAvroSchema(wio.Writer,projectID,schemaID,avscFilestring)error{// projectID := "my-project-id"// schemaID := "my-schema"// avscFile = "path/to/an/avro/schema/file(.avsc)/formatted/in/json"ctx:=context.Background()client,err:=pubsub.NewSchemaClient(ctx)iferr!=nil{returnfmt.Errorf("pubsub.NewSchemaClient: %w",err)}deferclient.Close()avscSource,err:=os.ReadFile(avscFile)iferr!=nil{returnfmt.Errorf("error reading from file: %s",avscFile)}req:=&pubsubpb.CreateSchemaRequest{Parent:fmt.Sprintf("projects/%s",projectID),Schema:&pubsubpb.Schema{Type:pubsubpb.Schema_AVRO,Definition:string(avscSource),},SchemaId:schemaID,}s,err:=client.CreateSchema(ctx,req)iferr!=nil{returnfmt.Errorf("error calling CreateSchema: %w",err)}fmt.Fprintf(w,"Schema created: %#v\n",s)returnnil}Proto
import("context""fmt""io""os"pubsub"cloud.google.com/go/pubsub/v2/apiv1""cloud.google.com/go/pubsub/v2/apiv1/pubsubpb")// createProtoSchema creates a schema resource from a schema proto file.funccreateProtoSchema(wio.Writer,projectID,schemaID,protoFilestring)error{// projectID := "my-project-id"// schemaID := "my-schema"// protoFile = "path/to/a/proto/schema/file(.proto)/formatted/in/protocol/buffers"ctx:=context.Background()client,err:=pubsub.NewSchemaClient(ctx)iferr!=nil{returnfmt.Errorf("pubsub.NewSchemaClient: %w",err)}deferclient.Close()protoSource,err:=os.ReadFile(protoFile)iferr!=nil{returnfmt.Errorf("error reading from file: %s",protoFile)}req:=&pubsubpb.CreateSchemaRequest{Parent:fmt.Sprintf("projects/%s",projectID),Schema:&pubsubpb.Schema{Type:pubsubpb.Schema_PROTOCOL_BUFFER,Definition:string(protoSource),},SchemaId:schemaID,}s,err:=client.CreateSchema(ctx,req)iferr!=nil{returnfmt.Errorf("error calling CreateSchema: %w",err)}fmt.Fprintf(w,"Schema created: %#v\n",s)returnnil}Java
Before trying this sample, follow the Java setup instructions inQuickstart: Using Client Libraries. For more information, see thePub/Sub Java API reference documentation.
Avro
importcom.google.api.gax.rpc.AlreadyExistsException;importcom.google.cloud.pubsub.v1.SchemaServiceClient;importcom.google.pubsub.v1.ProjectName;importcom.google.pubsub.v1.Schema;importcom.google.pubsub.v1.SchemaName;importjava.io.IOException;importjava.nio.file.Files;importjava.nio.file.Paths;publicclassCreateAvroSchemaExample{publicstaticvoidmain(String...args)throwsException{// TODO(developer): Replace these variables before running the sample.StringprojectId="your-project-id";StringschemaId="your-schema-id";StringavscFile="path/to/an/avro/schema/file/(.avsc)/formatted/in/json";createAvroSchemaExample(projectId,schemaId,avscFile);}publicstaticSchemacreateAvroSchemaExample(StringprojectId,StringschemaId,StringavscFile)throwsIOException{ProjectNameprojectName=ProjectName.of(projectId);SchemaNameschemaName=SchemaName.of(projectId,schemaId);// Read an Avro schema file formatted in JSON as a string.StringavscSource=newString(Files.readAllBytes(Paths.get(avscFile)));try(SchemaServiceClientschemaServiceClient=SchemaServiceClient.create()){Schemaschema=schemaServiceClient.createSchema(projectName,Schema.newBuilder().setName(schemaName.toString()).setType(Schema.Type.AVRO).setDefinition(avscSource).build(),schemaId);System.out.println("Created a schema using an Avro schema:\n"+schema);returnschema;}catch(AlreadyExistsExceptione){System.out.println(schemaName+"already exists.");returnnull;}}}Proto
importcom.google.api.gax.rpc.AlreadyExistsException;importcom.google.cloud.pubsub.v1.SchemaServiceClient;importcom.google.pubsub.v1.ProjectName;importcom.google.pubsub.v1.Schema;importcom.google.pubsub.v1.SchemaName;importjava.io.IOException;importjava.nio.file.Files;importjava.nio.file.Paths;publicclassCreateProtoSchemaExample{publicstaticvoidmain(String...args)throwsException{// TODO(developer): Replace these variables before running the sample.StringprojectId="your-project-id";StringschemaId="your-schema-id";StringprotoFile="path/to/a/proto/file/(.proto)/formatted/in/protocol/buffers";createProtoSchemaExample(projectId,schemaId,protoFile);}publicstaticSchemacreateProtoSchemaExample(StringprojectId,StringschemaId,StringprotoFile)throwsIOException{ProjectNameprojectName=ProjectName.of(projectId);SchemaNameschemaName=SchemaName.of(projectId,schemaId);// Read a proto file as a string.StringprotoSource=newString(Files.readAllBytes(Paths.get(protoFile)));try(SchemaServiceClientschemaServiceClient=SchemaServiceClient.create()){Schemaschema=schemaServiceClient.createSchema(projectName,Schema.newBuilder().setName(schemaName.toString()).setType(Schema.Type.PROTOCOL_BUFFER).setDefinition(protoSource).build(),schemaId);System.out.println("Created a schema using a protobuf schema:\n"+schema);returnschema;}catch(AlreadyExistsExceptione){System.out.println(schemaName+"already exists.");returnnull;}}}Node.js
Before trying this sample, follow the Node.js setup instructions inQuickstart: Using Client Libraries. For more information, see thePub/Sub Node.js API reference documentation.
Avro
/** * TODO(developer): Uncomment these variables before running the sample. */// const schemaNameOrId = 'YOUR_SCHEMA_NAME_OR_ID';// const avscFile = 'path/to/an/avro/schema/file/(.avsc)/formatted/in/json';// Imports the Google Cloud client libraryconst{PubSub,SchemaTypes}=require('@google-cloud/pubsub');constfs=require('fs');// Creates a client; cache this for further useconstpubSubClient=newPubSub();asyncfunctioncreateAvroSchema(schemaNameOrId,avscFile){constdefinition=fs.readFileSync(avscFile).toString();constschema=awaitpubSubClient.createSchema(schemaNameOrId,SchemaTypes.Avro,definition,);constname=awaitschema.getName();console.log(`Schema${name} created.`);}Proto
/** * TODO(developer): Uncomment these variables before running the sample. */// const schemaNameOrId = 'YOUR_SCHEMA_NAME_OR_ID';// const protoFile = 'path/to/a/proto/schema/file/(.proto)/formatted/in/protcol/buffers';// Imports the Google Cloud client libraryconst{PubSub,SchemaTypes}=require('@google-cloud/pubsub');constfs=require('fs');// Creates a client; cache this for further useconstpubSubClient=newPubSub();asyncfunctioncreateProtoSchema(schemaNameOrId,protoFile){constdefinition=fs.readFileSync(protoFile).toString();constschema=awaitpubSubClient.createSchema(schemaNameOrId,SchemaTypes.ProtocolBuffer,definition,);constfullName=awaitschema.getName();console.log(`Schema${fullName} created.`);}Node.js
Before trying this sample, follow the Node.js setup instructions inQuickstart: Using Client Libraries. For more information, see thePub/Sub Node.js API reference documentation.
Avro
/** * TODO(developer): Uncomment these variables before running the sample. */// const schemaNameOrId = 'YOUR_SCHEMA_NAME_OR_ID';// const avscFile = 'path/to/an/avro/schema/file/(.avsc)/formatted/in/json';// Imports the Google Cloud client libraryimport{PubSub,SchemaTypes}from'@google-cloud/pubsub';import*asfsfrom'fs';// Creates a client; cache this for further useconstpubSubClient=newPubSub();asyncfunctioncreateAvroSchema(schemaNameOrId:string,avscFile:string){constdefinition:string=fs.readFileSync(avscFile).toString();constschema=awaitpubSubClient.createSchema(schemaNameOrId,SchemaTypes.Avro,definition,);constname=awaitschema.getName();console.log(`Schema${name} created.`);}Proto
/** * TODO(developer): Uncomment these variables before running the sample. */// const schemaNameOrId = 'YOUR_SCHEMA_NAME_OR_ID';// const protoFile = 'path/to/a/proto/schema/file/(.proto)/formatted/in/protcol/buffers';// Imports the Google Cloud client libraryimport{PubSub,SchemaTypes}from'@google-cloud/pubsub';import*asfsfrom'fs';// Creates a client; cache this for further useconstpubSubClient=newPubSub();asyncfunctioncreateProtoSchema(schemaNameOrId:string,protoFile:string){constdefinition:string=fs.readFileSync(protoFile).toString();constschema=awaitpubSubClient.createSchema(schemaNameOrId,SchemaTypes.ProtocolBuffer,definition,);constfullName:string=awaitschema.getName();console.log(`Schema${fullName} created.`);}PHP
Before trying this sample, follow the PHP setup instructions inQuickstart: Using Client Libraries. For more information, see thePub/Sub PHP API reference documentation.
Avro
use Google\Cloud\PubSub\PubSubClient;/** * Create a Schema with an AVRO definition. * * @param string $projectId * @param string $schemaId * @param string $avscFile */function create_avro_schema(string $projectId, string $schemaId, string $avscFile): void{ $pubsub = new PubSubClient([ 'projectId' => $projectId, ]); $definition = (string) file_get_contents($avscFile); $schema = $pubsub->createSchema($schemaId, 'AVRO', $definition); printf('Schema %s created.', $schema->name());}Proto
use Google\Cloud\PubSub\PubSubClient;/** * Create a Schema with an Protocol Buffer definition. * * @param string $projectId * @param string $schemaId * @param string $protoFile */function create_proto_schema($projectId, $schemaId, $protoFile){ $pubsub = new PubSubClient([ 'projectId' => $projectId, ]); $definition = (string) file_get_contents($protoFile); $schema = $pubsub->createSchema($schemaId, 'PROTOCOL_BUFFER', $definition); printf('Schema %s created.', $schema->name());}Python
Before trying this sample, follow the Python setup instructions inQuickstart: Using Client Libraries. For more information, see thePub/Sub Python API reference documentation.
Avro
fromgoogle.api_core.exceptionsimportAlreadyExistsfromgoogle.cloud.pubsubimportSchemaServiceClientfromgoogle.pubsub_v1.typesimportSchema# TODO(developer): Replace these variables before running the sample.# project_id = "your-project-id"# schema_id = "your-schema-id"# avsc_file = "path/to/an/avro/schema/file/(.avsc)/formatted/in/json"project_path=f"projects/{project_id}"# Read a JSON-formatted Avro schema file as a string.withopen(avsc_file,"rb")asf:avsc_source=f.read().decode("utf-8")schema_client=SchemaServiceClient()schema_path=schema_client.schema_path(project_id,schema_id)schema=Schema(name=schema_path,type_=Schema.Type.AVRO,definition=avsc_source)try:result=schema_client.create_schema(request={"parent":project_path,"schema":schema,"schema_id":schema_id})print(f"Created a schema using an Avro schema file:\n{result}")returnresultexceptAlreadyExists:print(f"{schema_id} already exists.")Proto
fromgoogle.api_core.exceptionsimportAlreadyExistsfromgoogle.cloud.pubsubimportSchemaServiceClientfromgoogle.pubsub_v1.typesimportSchema# TODO(developer): Replace these variables before running the sample.# project_id = "your-project-id"# schema_id = "your-schema-id"# proto_file = "path/to/a/proto/file/(.proto)/formatted/in/protocol/buffers"project_path=f"projects/{project_id}"# Read a protobuf schema file as a string.withopen(proto_file,"rb")asf:proto_source=f.read().decode("utf-8")schema_client=SchemaServiceClient()schema_path=schema_client.schema_path(project_id,schema_id)schema=Schema(name=schema_path,type_=Schema.Type.PROTOCOL_BUFFER,definition=proto_source)try:result=schema_client.create_schema(request={"parent":project_path,"schema":schema,"schema_id":schema_id})print(f"Created a schema using a protobuf schema file:\n{result}")returnresultexceptAlreadyExists:print(f"{schema_id} already exists.")Ruby
The following sample uses Ruby Pub/Sub client library v3. If you are still using the v2 library, see the migration guide to v3.To see a list of Ruby v2 code samples, seethe deprecated code samples.
Before trying this sample, follow the Ruby setup instructions inQuickstart: Using Client Libraries.For more information, see thePub/Sub Ruby API reference documentation.
Avro
# schema_id = "your-schema-id"# avsc_file = "path/to/an/avro/schema/file/(.avsc)/formatted/in/json"pubsub=Google::Cloud::PubSub.newschemas=pubsub.schemasschema=schemas.create_schemaparent:pubsub.project_path,schema:{name:schema_id,type::AVRO,definition:File.read(avsc_file)},schema_id:schema_idputs"Schema#{schema.name} created."Proto
# schema_id = "your-schema-id"# proto_file = "path/to/a/proto/file/(.proto)/formatted/in/protocol/buffers"pubsub=Google::Cloud::PubSub.newschemas=pubsub.schemasschema=Google::Cloud::PubSub::V1::Schema.new\name:schema_id,type::PROTOCOL_BUFFER,definition:File.read(proto_file)schema=schemas.create_schemaparent:pubsub.project_path,schema:schema,schema_id:schema_idputs"Schema#{schema.name} created."After a schema is created, you cansee the details of the schema in theSchemas page.
You canassociate the schema with a topic.
What's next
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2026-02-19 UTC.