gRPC API Testing
This guide provides comprehensive examples for testing the PermitProof gRPC API. The API can be accessed in two ways:
- Direct gRPC Backend - Calls the Cloud Run gRPC service directly
- gRPC via ESPv2 Gateway - Calls through the ESPv2 proxy (Cloud Endpoints)
Authentication
Direct gRPC Backend
Direct gRPC calls require only the authorization header:
# Generate Firebase bearer token
CODEPROOF_FIREBASE_TOKEN=$(./firebase-token-generator/generate-token.sh sanchos101@gmail.com)
# Set gRPC server host (dev environment)
GRPC_SERVER_HOST=construction-code-expert-dev-856365345080.us-central1.run.app
gRPC via ESPv2 Gateway
ESPv2 gateway calls require both authorization and x-original-authorization headers:
# Generate Firebase bearer token
CODEPROOF_FIREBASE_TOKEN=$(./firebase-token-generator/generate-token.sh sanchos101@gmail.com)
# Set ESPv2 service host (dev environment)
ESP_SERVICE_HOST=construction-code-expert-esp2-dev-6yieikr6ca-uc.a.run.app
Key Difference: ESPv2 requires both headers for proper authentication flow through the gateway.
Service Discovery
List available services and methods using gRPC reflection:
# List all services (direct gRPC)
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
${GRPC_SERVER_HOST}:443 \
list
# Describe a specific service
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
${GRPC_SERVER_HOST}:443 \
describe org.codetricks.construction.code.assistant.service.ArchitecturalPlanService
# List services via ESPv2
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-H "x-original-authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
${ESP_SERVICE_HOST}:443 \
list
Note: Service discovery works because gRPC reflection is enabled on the server.
ArchitecturalPlanService
GetArchitecturalPlan
Get project metadata and page list:
# Direct gRPC
grpcurl -import-path src/main/proto \
-proto src/main/proto/api.proto \
-H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{"architectural_plan_id": "R2024.0091-2024-10-14"}' \
${GRPC_SERVER_HOST}:443 \
org.codetricks.construction.code.assistant.service.ArchitecturalPlanService/GetArchitecturalPlan
# Via ESPv2
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-H "x-original-authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{"architectural_plan_id": "R2024.0091-2024-10-14"}' \
${ESP_SERVICE_HOST}:443 \
org.codetricks.construction.code.assistant.service.ArchitecturalPlanService/GetArchitecturalPlan
GetArchitecturalPlanPagePdf
Retrieve PDF content for a specific page:
# Direct gRPC (note: use -max-msg-sz for large PDFs)
grpcurl -import-path src/main/proto \
-proto src/main/proto/api.proto \
-H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{"architectural_plan_id": "R2024.0091-2024-10-14", "page_number": 1}' \
-max-msg-sz $((10 * 1024 * 1024)) \
${GRPC_SERVER_HOST}:443 \
org.codetricks.construction.code.assistant.service.ArchitecturalPlanService/GetArchitecturalPlanPagePdf
# Via ESPv2
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-H "x-original-authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{"architectural_plan_id": "R2024.0091-2024-10-14", "page_number": 1}' \
-max-msg-sz $((10 * 1024 * 1024)) \
${ESP_SERVICE_HOST}:443 \
org.codetricks.construction.code.assistant.service.ArchitecturalPlanService/GetArchitecturalPlanPagePdf
Note: Some PDF pages can exceed 4MB (default gRPC message size), so -max-msg-sz is required.
ArchitecturalPlanReviewService
GetApplicableCodeSections
Get applicable code sections for a specific page (from GitHub Issue #182):
# Set project variables
PROJECT_ID="US.CA.SanJose-1550-Tech.Dr-rev2002-07-09"
PAGE_NUMBER=2
ICC_BOOK_ID="3701"
# Direct gRPC (using heredoc for readability)
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d @ \
${GRPC_SERVER_HOST}:443 \
org.codetricks.construction.code.assistant.service.ArchitecturalPlanReviewService/GetApplicableCodeSections \
<<EOF
{
"architectural_plan_id": "${PROJECT_ID}",
"page_number": ${PAGE_NUMBER},
"icc_book_id": "${ICC_BOOK_ID}"
}
EOF
# Via ESPv2
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-H "x-original-authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d @ \
${ESP_SERVICE_HOST}:443 \
org.codetricks.construction.code.assistant.service.ArchitecturalPlanReviewService/GetApplicableCodeSections \
<<EOF
{
"architectural_plan_id": "${PROJECT_ID}",
"page_number": ${PAGE_NUMBER},
"icc_book_id": "${ICC_BOOK_ID}"
}
EOF
Note: Proto path and imports can be omitted when using service discovery (reflection enabled).
GetIccBookTableOfContents
Get the table of contents for an ICC book:
# Direct gRPC
grpcurl -import-path src/main/proto \
-import-path env/dependencies/googleapis \
-proto src/main/proto/api.proto \
-H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{"icc_book_id": "2217"}' \
${GRPC_SERVER_HOST}:443 \
org.codetricks.construction.code.assistant.service.ArchitecturalPlanReviewService/GetIccBookTableOfContents
# Via ESPv2
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-H "x-original-authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{"icc_book_id": "2217"}' \
${ESP_SERVICE_HOST}:443 \
org.codetricks.construction.code.assistant.service.ArchitecturalPlanReviewService/GetIccBookTableOfContents
CodeApplicabilityService
StartAsyncCodeApplicabilityAnalysis
Trigger asynchronous code applicability analysis (from GitHub Issue #179):
# Direct gRPC
grpcurl -import-path src/main/proto \
-import-path env/dependencies/googleapis \
-proto src/main/proto/code_applicability.proto \
-H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{
"architectural_project_id": "US.CA.SanJose-1550-Tech.Dr-rev2002-07-09",
"page_number": 2,
"icc_book_id": "3701",
"max_relevant_chapters": 5
}' \
${GRPC_SERVER_HOST}:443 \
org.codetricks.construction.code.assistant.service.applicability.CodeApplicabilityService/StartCodeApplicabilityAnalysisTask
# Via ESPv2
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-H "x-original-authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{
"architectural_project_id": "US.CA.SanJose-1550-Tech.Dr-rev2002-07-09",
"page_number": 2,
"icc_book_id": "3701",
"max_relevant_chapters": 5
}' \
${ESP_SERVICE_HOST}:443 \
org.codetricks.construction.code.assistant.service.applicability.CodeApplicabilityService/StartCodeApplicabilityAnalysisTask
Expected Response:
{
"taskId": "550e8400-e29b-41d4-a716-446655440000",
"success": true,
"message": "Code applicability analysis started"
}
ComplianceCodeSearchService
GetIccCodeSearchResults
Perform semantic search across ICC code sections:
# Direct gRPC
grpcurl -import-path src/main/proto \
-import-path env/dependencies/googleapis \
-proto src/main/proto/api.proto \
-H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{
"icc_book_id": "2217",
"query": "Cooling towers located on a roof of a building shall be constructed of non-combustible materials when the base area of the cooling tower is greater than how many square feet?",
"max_results": 3
}' \
${GRPC_SERVER_HOST}:443 \
org.codetricks.construction.code.assistant.service.ComplianceCodeSearchService/GetIccCodeSearchResults
# Via ESPv2
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-H "x-original-authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{
"icc_book_id": "2217",
"query": "Cooling towers",
"max_results": 3
}' \
${ESP_SERVICE_HOST}:443 \
org.codetricks.construction.code.assistant.service.ComplianceCodeSearchService/GetIccCodeSearchResults
RBACService
GetUserProjects
List projects accessible to a user (from GitHub Issue #136):
# Direct gRPC
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{"user_email": "sanchos101@gmail.com"}' \
${GRPC_SERVER_HOST}:443 \
org.codetricks.auth.rbac.RBACService/GetUserProjects
# Via ESPv2
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-H "x-original-authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{"user_email": "sanchos101@gmail.com"}' \
${ESP_SERVICE_HOST}:443 \
org.codetricks.auth.rbac.RBACService/GetUserProjects
GetProjectMembers
Get list of users who have access to a project:
# Direct gRPC
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{"project_id": "R2024.0091-2024-10-14"}' \
${GRPC_SERVER_HOST}:443 \
org.codetricks.auth.rbac.RBACService/GetProjectMembers
# Via ESPv2
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-H "x-original-authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{"project_id": "R2024.0091-2024-10-14"}' \
${ESP_SERVICE_HOST}:443 \
org.codetricks.auth.rbac.RBACService/GetProjectMembers
ArchitecturalPlanWriteService
CreateArchitecturalPlan
Create a new project (from GitHub Issue #214):
# Direct gRPC
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{"project_id": "TestProject", "project_name": "Test Project"}' \
${GRPC_SERVER_HOST}:443 \
org.codetricks.construction.code.assistant.service.ArchitecturalPlanWriteService/CreateArchitecturalPlan
# Via ESPv2
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-H "x-original-authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{"project_id": "TestProject2", "project_name": "Test Project 2"}' \
${ESP_SERVICE_HOST}:443 \
org.codetricks.construction.code.assistant.service.ArchitecturalPlanWriteService/CreateArchitecturalPlan
IccBookInfoService
GetIccBookInfo
Get metadata for a specific ICC book (from GitHub Issue #185):
# Direct gRPC
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{"document_id": "3701"}' \
${GRPC_SERVER_HOST}:443 \
org.codetricks.construction.code.assistant.io.icc.api.IccBookInfoService/GetIccBookInfo
# Via ESPv2
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-H "x-original-authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{"document_id": "3701"}' \
${ESP_SERVICE_HOST}:443 \
org.codetricks.construction.code.assistant.io.icc.api.IccBookInfoService/GetIccBookInfo
GetAvailableBookInfo
List all available ICC books:
# Direct gRPC
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{}' \
${GRPC_SERVER_HOST}:443 \
org.codetricks.construction.code.assistant.io.icc.api.IccBookInfoService/GetAvailableBookInfo
# Via ESPv2
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-H "x-original-authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{}' \
${ESP_SERVICE_HOST}:443 \
org.codetricks.construction.code.assistant.io.icc.api.IccBookInfoService/GetAvailableBookInfo
AccessControlListService
GetAuthorizationStatus
Check if a user is authorized to access the application:
# Direct gRPC
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{"client_email": "sanchos101@gmail.com"}' \
${GRPC_SERVER_HOST}:443 \
org.codetricks.auth.AccessControlListService/GetAuthorizationStatus
# Via ESPv2
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-H "x-original-authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{"client_email": "sanchos101@gmail.com"}' \
${ESP_SERVICE_HOST}:443 \
org.codetricks.auth.AccessControlListService/GetAuthorizationStatus
Common Book IDs
For testing code applicability and compliance APIs:
2217- IBC 20213123- IBC 2021 (NJ Edition)3701- California Building Code 20223815- Florida Building Code 20233100- ICC/ANSI A117.1-2017 (Accessibility)1156- ICC 300-20173757- IRC 2021 (International Residential Code)
Troubleshooting
Authentication Errors
Problem: Code: Unauthenticated or Invalid JWT format
Solutions:
- Regenerate token: Tokens expire after 1 hour
- Check header format: Use lowercase
authorization(notAuthorization) - Verify user is allowlisted: Check Google Group membership
- ESPv2 calls: Ensure both headers are present
Service Not Found Errors
Problem: Code: Unimplemented or service not found
Solutions:
- Check service name: Use full package path
- Verify deployment: Ensure latest backend is deployed
- Check ESPv2 config: Verify service is registered in
api_config.yaml - Use service discovery: Run
grpcurl listto see available services
Proto Import Errors
Problem: cannot resolve import or proto file not found
Solutions:
- Use service discovery: Omit
-import-pathand-protoflags when reflection is enabled - Check googleapis: Ensure
env/dependencies/googleapisis cloned - Verify proto paths: Use correct relative paths from project root
Message Size Errors
Problem: resource exhausted or message too large
Solutions:
- Increase message size: Use
-max-msg-sz $((10 * 1024 * 1024))for 10MB limit - Check PDF size: Some pages may exceed limits
- Use streaming: Consider implementing streaming RPCs for large data
Local Development Testing
For testing against localhost (from GitHub Issue #129):
# Start local gRPC server
source env/dev/setvars.sh
mvn exec:java -Dexec.mainClass="org.codetricks.construction.code.assistant.service.ArchitecturalPlanServer"
# Test against localhost (no TLS, use -plaintext)
grpcurl -plaintext \
-H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
localhost:8080 \
list
# Call a method on localhost
grpcurl -plaintext \
-H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{"architectural_plan_id": "R2024.0091-2024-10-14"}' \
localhost:8080 \
org.codetricks.construction.code.assistant.service.ArchitecturalPlanService/GetArchitecturalPlan
Note: Local development uses -plaintext flag (no TLS). Cloud Run deployments use TLS on port 443.
Advanced Usage
Using Heredoc for Complex Requests
For requests with many fields or complex JSON, use heredoc syntax:
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d @ \
${GRPC_SERVER_HOST}:443 \
org.codetricks.construction.code.assistant.service.ArchitecturalPlanReviewService/GetApplicableCodeSections \
<<EOF
{
"architectural_plan_id": "${PROJECT_ID}",
"page_number": ${PAGE_NUMBER},
"icc_book_id": "${ICC_BOOK_ID}"
}
EOF
Piping Output to jq
Format and filter JSON responses using jq:
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" \
-d '{"architectural_plan_id": "R2024.0091-2024-10-14"}' \
${GRPC_SERVER_HOST}:443 \
org.codetricks.construction.code.assistant.service.ArchitecturalPlanService/GetArchitecturalPlan \
| jq '.pages[] | {pageNumber, pageTitle}'
Testing Multiple Environments
# Test against dev
GRPC_SERVER_HOST=construction-code-expert-dev-856365345080.us-central1.run.app
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" ...
# Test against test
GRPC_SERVER_HOST=construction-code-expert-test-856365345080.us-central1.run.app
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" ...
# Test against demo
GRPC_SERVER_HOST=construction-code-expert-demo-856365345080.us-central1.run.app
grpcurl -H "authorization: Bearer ${CODEPROOF_FIREBASE_TOKEN}" ...
Related Documentation
- REST API Testing - Testing REST endpoints via ESPv2
- Release Management - Deployment workflows
- gRPC Playbook - Local gRPC development
- gRPC Gateway Playbook - ESPv2 configuration