Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions apihub-curation/enrich-with-specs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
***

# Enrich API Data with Custom Curation in Apigee API Hub

![Architecture](enrich-with-spec.png)

This sample shows how **Apigee API hub** can be configured with custom curation logic to enrich API metadata automatically. It uses Application Integration to define a workflow that fetches OpenAPI specifications from a Cloud Storage bucket and attaches them to the corresponding API versionss registered in API hub from an Apigee instance.

## Prerequisites

* A Google Cloud project with billing enabled.
* The following services provisioned in your Google Cloud project:
* Apigee
* Apigee API hub
* Application Integration
* Integration Connectors
* A service account with the following IAM roles:
* `roles/secretmanager.viewer`
* `roles/secretmanager.secretAccessor`
* `roles/storage.admin`
* The Cloud Storage API enabled in your project
* Sample files from the tutorial downloaded to your local machine:
* enrich-with-spec.json
* specs/orders-api.yaml
* specs/products-api.yaml
* specs/users-api.yaml

## Setup instructions

### Step 1: Prepare the environment

To begin, you will prepare your Apigee, Cloud Storage, and Integration Connectors environment.

1. **Create API Proxies in Apigee**: Register three sample API proxies (`Orders API`, `Products API`, `Users API`) in your Apigee project and ensure they are deployed ([source](https://cloud.devsite.corp.google.com/apigee/docs/apihub/tutorials/enrich-api-data?content_ref=enable%20the%20cloud%20storage%20api#create_api_proxies_in)). These will be automatically discovered by the API hub plugin.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pointing to devsite URL

2. **Set up Cloud Storage**: Create a Cloud Storage bucket (e.g., `test_bucket`) ([source](https://cloud.devsite.corp.google.com/apigee/docs/apihub/tutorials/enrich-api-data?content_ref=enable%20the%20cloud%20storage%20api#set_up)). Upload the three sample API specification files (`orders-api.yaml`, `products-api.yaml`, `users-api.yaml`) to this bucket ([source](https://cloud.devsite.corp.google.com/apigee/docs/apihub/tutorials/enrich-api-data?content_ref=enable%20the%20cloud%20storage%20api#upload_api_specification_files)).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

devsite URL

3. **Configure Cloud Storage Connection**: In Integration Connectors, create a new Cloud Storage connection named `fetch-specs` ([source](https://cloud.devsite.corp.google.com/apigee/docs/apihub/tutorials/enrich-api-data?content_ref=enable%20the%20cloud%20storage%20api#configure_connection)). Configure it to use the service account you created earlier. This allows the integration to access the bucket.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

devsite URL


### Step 2: Create an integration for custom curation

This step will create the custom logic in Application Integration that fetches and attaches the specs.

1. **Create an Integration**: In the Application Integration UI, create a new integration named `test-curation` in the same region as API hub (e.g., `us-central1`) ([source](https://cloud.devsite.corp.google.com/apigee/docs/apihub/tutorials/enrich-api-data?content_ref=enable%20the%20cloud%20storage%20api#step1)).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

devsite URL

2. **Upload and Configure**: Upload the `enrich-with-spec-yaml.json` file to create a new version of the integration. Configure the `Fetch spec from GCS` connector task to use the `fetch-specs` connection you created ([source](https://cloud.devsite.corp.google.com/apigee/docs/apihub/tutorials/enrich-api-data?content_ref=enable%20the%20cloud%20storage%20api#configure_connector_task_in_the_integration)).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

devsite URL

3. **Test and Publish**: Test the integration with the sample input provided in the tutorial to ensure it correctly constructs the enriched API data payload ([source](https://cloud.devsite.corp.google.com/apigee/docs/apihub/tutorials/enrich-api-data?content_ref=enable%20the%20cloud%20storage%20api#test_and_publish_the_integration)). After a successful test, publish the integration to make it active.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

devsite URL


### Step 3: Set up and verify custom curation in API hub

Now, you will configure API hub to use the integration you just published.

1. **Set Up Custom Curation**: In the API hub **Settings > Curations** tab, set up a new curation named `enrich-curation` ([source](https://cloud.devsite.corp.google.com/apigee/docs/apihub/tutorials/enrich-api-data?content_ref=enable%20the%20cloud%20storage%20api#step2)). Associate it with your `test-curation` integration by selecting the correct integration and its API trigger ID.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

devsite URL

2. **Edit the Plugin Instance**: Navigate to the **Plugins** tab and edit the default **Apigee X and Hybrid** plugin instance ([source](https://cloud.devsite.corp.google.com/apigee/docs/apihub/tutorials/enrich-api-data?content_ref=enable%20the%20cloud%20storage%20api#step3)). Change its Curation logic from the default to your newly created `enrich-curation` custom curation.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

devsite URL

3. **Verify Enriched Data**: Go to the **APIs** page in API hub. After the plugin runs, you will see that the `DemoAPI` proxies are now enriched with their corresponding specification files from the Cloud Storage bucket ([source](https://cloud.devsite.corp.google.com/apigee/docs/apihub/tutorials/enrich-api-data?content_ref=enable%20the%20cloud%20storage%20api#step4)).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

devsite URL


### Step 4: Clean up resources

To avoid incurring charges, clean up the resources created during this tutorial. You can either delete the entire Google Cloud project or delete the individual resources you created, such as the Cloud Storage bucket ([source](https://cloud.devsite.corp.google.com/apigee/docs/apihub/tutorials/enrich-api-data?content_ref=enable%20the%20cloud%20storage%20api#clean-up)).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

devsite URL


```bash
# To delete the Cloud Storage bucket
gcloud storage buckets delete BUCKET_NAME

# To delete the project
gcloud projects delete PROJECT_ID
```

Congrats, you have successfully used Application Integration to create a custom curation workflow that automatically enriches API data in API hub from an external source.
69 changes: 69 additions & 0 deletions apihub-curation/enrich-with-specs/artifacts/sample_input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
Copy link
Collaborator

@ssvaidyanathan ssvaidyanathan Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are the files .txt and not .json?

"apiMetadataList": {
"apiMetadata": [
{
"api": {
"name": "projects/api-hub-demo-5/locations/us-central1/apis/api-hub-demo-5-Products-API",
"displayName": "Products-API",
"fingerprint": "products-api"
},
"versions": [
{
"version": {
"name": "projects/api-hub-demo-5/locations/us-central1/apis/api-hub-demo-5-Products-API/versions/version-1",
"displayName": "version-1"
},
"deployments": [
{
"deployment": {
"displayName": "Products-API",
"description": "API for managing product inventory. This API allows for the creation, retrieval, update, and deletion of product records.",
"deploymentType": {
"enumValues": {
"values": [
{
"id": "apigee"
}
]
},
"attribute": "projects/api-hub-demo-5/locations/us-central1/attributes/system-deployment-type"
},
"resourceUri": "organizations/api-hub-demo-5/apis/Products-API/revisions/1/environments/test-env",
"endpoints": [
"https://googleapis.com/products-api"
],
"attributes": {
"projects/api-hub-demo-5/locations/us-central1/attributes/plugin-system-apigee-x-and-hybrid-environment": {
"stringValues": {
"values": [
"test-env"
]
},
"attribute": "projects/api-hub-demo-5/locations/us-central1/attributes/plugin-system-apigee-x-and-hybrid-environment"
},
"projects/api-hub-demo-5/locations/us-central1/attributes/plugin-system-apigee-x-and-hybrid-organization": {
"stringValues": {
"values": [
"api-hub-demo-5"
]
},
"attribute": "projects/api-hub-demo-5/locations/us-central1/attributes/plugin-system-apigee-x-and-hybrid-organization"
}
}
},
"originalId": "apis/Products-API/revisions/1/environments/test-env",
"originalCreateTime": "2025-07-07T05:23:51.617Z",
"originalUpdateTime": "2025-07-07T05:23:51.617Z"
}
],
"originalId": "apis/Products-API/revisions/1",
"originalCreateTime": "2025-07-07T05:23:47.982Z",
"originalUpdateTime": "2025-07-07T05:23:47.982Z"
}
],
"originalId": "apis/Products-API",
"originalUpdateTime": "2025-07-07T05:23:47.982Z"
}
]
}
}
90 changes: 90 additions & 0 deletions apihub-curation/enrich-with-specs/artifacts/sample_output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
{
Copy link
Collaborator

@ssvaidyanathan ssvaidyanathan Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are the files .txt and not .json?

"apiMetadataList": {
"apiMetadata": [
{
"api": {
"name": "projects/api-hub-demo-5/locations/us-central1/apis/api-hub-demo-5-Products-API",
"displayName": "Products-API",
"fingerprint": "products-api"
},
"versions": [
{
"version": {
"name": "projects/api-hub-demo-5/locations/us-central1/apis/api-hub-demo-5-Products-API/versions/version-1",
"displayName": "version-1"
},
"deployments": [
{
"deployment": {
"displayName": "Products-API",
"description": "API for managing product inventory. This API allows for the creation, retrieval, update, and deletion of product records.",
"deploymentType": {
"enumValues": {
"values": [
{
"id": "apigee"
}
]
},
"attribute": "projects/api-hub-demo-5/locations/us-central1/attributes/system-deployment-type"
},
"resourceUri": "organizations/api-hub-demo-5/apis/Products-API/revisions/1/environments/test-env",
"endpoints": [
"https://googleapis.com/products-api"
],
"attributes": {
"projects/api-hub-demo-5/locations/us-central1/attributes/plugin-system-apigee-x-and-hybrid-environment": {
"stringValues": {
"values": [
"test-env"
]
},
"attribute": "projects/api-hub-demo-5/locations/us-central1/attributes/plugin-system-apigee-x-and-hybrid-environment"
},
"projects/api-hub-demo-5/locations/us-central1/attributes/plugin-system-apigee-x-and-hybrid-organization": {
"stringValues": {
"values": [
"api-hub-demo-5"
]
},
"attribute": "projects/api-hub-demo-5/locations/us-central1/attributes/plugin-system-apigee-x-and-hybrid-organization"
}
}
},
"originalId": "apis/Products-API/revisions/1/environments/test-env",
"originalCreateTime": "2025-07-07T05:23:51.617Z",
"originalUpdateTime": "2025-07-07T05:23:51.617Z"
}
],
"originalId": "apis/Products-API/revisions/1",
"originalCreateTime": "2025-07-07T05:23:47.982Z",
"originalUpdateTime": "2025-07-07T05:23:47.982Z",
"specs": [
{
"originalModifiedTime": "2025-07-07T05:23:47.982Z",
"spec": {
"displayName": "open-api-spec",
"specType": {
"enumValues": {
"values": [
{
"id": "openapi"
}
]
}
},
"contents": {
"mimeType": "application/yaml",
"contents": "b3BlbmFwaTogMy4wLjAKaW5mbzoKICB0aXRsZTogUHJvZHVjdHMgQVBJCiAgdmVyc2lvbjogMS4wLjAKICBkZXNjcmlwdGlvbjogQVBJIGZvciBtYW5hZ2luZyBwcm9kdWN0IGludmVudG9yeS4gVGhpcyBBUEkgYWxsb3dzIGZvciB0aGUgY3JlYXRpb24sIHJldHJpZXZhbCwgdXBkYXRlLCBhbmQgZGVsZXRpb24gb2YgcHJvZHVjdCByZWNvcmRzLgpzZXJ2ZXJzOgogIC0gdXJsOiBodHRwczovL2FwaS5leGFtcGxlLmNvbS9wcm9kdWN0cy92MQogICAgZGVzY3JpcHRpb246IFByb2R1Y3Rpb24gc2VydmVyIGZvciB0aGUgUHJvZHVjdHMgQVBJLgpwYXRoczoKICAvcHJvZHVjdHM6CiAgICBnZXQ6CiAgICAgIHN1bW1hcnk6IEdldCBhbGwgcHJvZHVjdHMKICAgICAgb3BlcmF0aW9uSWQ6IGdldEFsbFByb2R1Y3RzCiAgICAgIHJlc3BvbnNlczoKICAgICAgICAnMjAwJzoKICAgICAgICAgIGRlc2NyaXB0aW9uOiBBIGxpc3Qgb2YgcHJvZHVjdHMgc3VjY2Vzc2Z1bGx5IHJldHJpZXZlZC4KICAgICAgICAgIGNvbnRlbnQ6CiAgICAgICAgICAgIGFwcGxpY2F0aW9uL2pzb246CiAgICAgICAgICAgICAgc2NoZW1hOgogICAgICAgICAgICAgICAgdHlwZTogYXJyYXkKICAgICAgICAgICAgICAgIGl0ZW1zOgogICAgICAgICAgICAgICAgICAkcmVmOiAnIy9jb21wb25lbnRzL3NjaGVtYXMvUHJvZHVjdCcKICAgIHBvc3Q6CiAgICAgIHN1bW1hcnk6IEFkZCBhIG5ldyBwcm9kdWN0CiAgICAgIG9wZXJhdGlvbklkOiBhZGRQcm9kdWN0CiAgICAgIHJlcXVlc3RCb2R5OgogICAgICAgIHJlcXVpcmVkOiB0cnVlCiAgICAgICAgZGVzY3JpcHRpb246IFByb2R1Y3QgZGF0YSB0byBiZSBhZGRlZC4KICAgICAgICBjb250ZW50OgogICAgICAgICAgYXBwbGljYXRpb24vanNvbjoKICAgICAgICAgICAgc2NoZW1hOgogICAgICAgICAgICAgICRyZWY6ICcjL2NvbXBvbmVudHMvc2NoZW1hcy9Qcm9kdWN0SW5wdXQnCiAgICAgIHJlc3BvbnNlczoKICAgICAgICAnMjAxJzoKICAgICAgICAgIGRlc2NyaXB0aW9uOiBQcm9kdWN0IHN1Y2Nlc3NmdWxseSBjcmVhdGVkLgogICAgICAgICAgY29udGVudDoKICAgICAgICAgICAgYXBwbGljYXRpb24vanNvbjoKICAgICAgICAgICAgICBzY2hlbWE6CiAgICAgICAgICAgICAgICAkcmVmOiAnIy9jb21wb25lbnRzL3NjaGVtYXMvUHJvZHVjdCcKICAgICAgICAnNDAwJzoKICAgICAgICAgIGRlc2NyaXB0aW9uOiBJbnZhbGlkIGlucHV0IHByb3ZpZGVkIGZvciBwcm9kdWN0IGNyZWF0aW9uLgogIC9wcm9kdWN0cy97cHJvZHVjdElkfToKICAgIGdldDoKICAgICAgc3VtbWFyeTogR2V0IGEgcHJvZHVjdCBieSBJRAogICAgICBvcGVyYXRpb25JZDogZ2V0UHJvZHVjdEJ5SWQKICAgICAgcGFyYW1ldGVyczoKICAgICAgICAtIG5hbWU6IHByb2R1Y3RJZAogICAgICAgICAgaW46IHBhdGgKICAgICAgICAgIHJlcXVpcmVkOiB0cnVlCiAgICAgICAgICBkZXNjcmlwdGlvbjogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIHByb2R1Y3QgdG8gcmV0cmlldmUuCiAgICAgICAgICBzY2hlbWE6CiAgICAgICAgICAgIHR5cGU6IHN0cmluZwogICAgICAgICAgICBmb3JtYXQ6IHV1aWQKICAgICAgcmVzcG9uc2VzOgogICAgICAgICcyMDAnOgogICAgICAgICAgZGVzY3JpcHRpb246IFByb2R1Y3QgZGV0YWlscyBzdWNjZXNzZnVsbHkgcmV0cmlldmVkLgogICAgICAgICAgY29udGVudDoKICAgICAgICAgICAgYXBwbGljYXRpb24vanNvbjoKICAgICAgICAgICAgICBzY2hlbWE6CiAgICAgICAgICAgICAgICAkcmVmOiAnIy9jb21wb25lbnRzL3NjaGVtYXMvUHJvZHVjdCcKICAgICAgICAnNDA0JzoKICAgICAgICAgIGRlc2NyaXB0aW9uOiBQcm9kdWN0IG5vdCBmb3VuZCB3aXRoIHRoZSBnaXZlbiBJRC4KICAgIHB1dDoKICAgICAgc3VtbWFyeTogVXBkYXRlIGFuIGV4aXN0aW5nIHByb2R1Y3QKICAgICAgb3BlcmF0aW9uSWQ6IHVwZGF0ZVByb2R1Y3QKICAgICAgcGFyYW1ldGVyczoKICAgICAgICAtIG5hbWU6IHByb2R1Y3RJZAogICAgICAgICAgaW46IHBhdGgKICAgICAgICAgIHJlcXVpcmVkOiB0cnVlCiAgICAgICAgICBkZXNjcmlwdGlvbjogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIHByb2R1Y3QgdG8gdXBkYXRlLgogICAgICAgICAgc2NoZW1hOgogICAgICAgICAgICB0eXBlOiBzdHJpbmcKICAgICAgICAgICAgZm9ybWF0OiB1dWlkCiAgICAgIHJlcXVlc3RCb2R5OgogICAgICAgIHJlcXVpcmVkOiB0cnVlCiAgICAgICAgZGVzY3JpcHRpb246IFVwZGF0ZWQgcHJvZHVjdCBkYXRhLgogICAgICAgIGNvbnRlbnQ6CiAgICAgICAgICBhcHBsaWNhdGlvbi9qc29uOgogICAgICAgICAgICBzY2hlbWE6CiAgICAgICAgICAgICAgJHJlZjogJyMvY29tcG9uZW50cy9zY2hlbWFzL1Byb2R1Y3RJbnB1dCcKICAgICAgcmVzcG9uc2VzOgogICAgICAgICcyMDAnOgogICAgICAgICAgZGVzY3JpcHRpb246IFByb2R1Y3Qgc3VjY2Vzc2Z1bGx5IHVwZGF0ZWQuCiAgICAgICAgJzQwMCc6CiAgICAgICAgICBkZXNjcmlwdGlvbjogSW52YWxpZCBpbnB1dCBwcm92aWRlZCBmb3IgcHJvZHVjdCB1cGRhdGUuCiAgICAgICAgJzQwNCc6CiAgICAgICAgICBkZXNjcmlwdGlvbjogUHJvZHVjdCBub3QgZm91bmQgd2l0aCB0aGUgZ2l2ZW4gSUQuCiAgICBkZWxldGU6CiAgICAgIHN1bW1hcnk6IERlbGV0ZSBhIHByb2R1Y3QKICAgICAgb3BlcmF0aW9uSWQ6IGRlbGV0ZVByb2R1Y3QKICAgICAgcGFyYW1ldGVyczoKICAgICAgICAtIG5hbWU6IHByb2R1Y3RJZAogICAgICAgICAgaW46IHBhdGgKICAgICAgICAgIHJlcXVpcmVkOiB0cnVlCiAgICAgICAgICBkZXNjcmlwdGlvbjogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIHByb2R1Y3QgdG8gZGVsZXRlLgogICAgICAgICAgc2NoZW1hOgogICAgICAgICAgICB0eXBlOiBzdHJpbmcKICAgICAgICAgICAgZm9ybWF0OiB1dWlkCiAgICAgIHJlc3BvbnNlczoKICAgICAgICAnMjA0JzoKICAgICAgICAgIGRlc2NyaXB0aW9uOiBQcm9kdWN0IHN1Y2Nlc3NmdWxseSBkZWxldGVkLiBObyBjb250ZW50LgogICAgICAgICc0MDQnOgogICAgICAgICAgZGVzY3JpcHRpb246IFByb2R1Y3Qgbm90IGZvdW5kIHdpdGggdGhlIGdpdmVuIElELgpjb21wb25lbnRzOgogIHNjaGVtYXM6CiAgICBQcm9kdWN0OgogICAgICB0eXBlOiBvYmplY3QKICAgICAgcmVxdWlyZWQ6CiAgICAgICAgLSBpZAogICAgICAgIC0gbmFtZQogICAgICAgIC0gcHJpY2UKICAgICAgcHJvcGVydGllczoKICAgICAgICBpZDoKICAgICAgICAgIHR5cGU6IHN0cmluZwogICAgICAgICAgZm9ybWF0OiB1dWlkCiAgICAgICAgICBkZXNjcmlwdGlvbjogVW5pcXVlIHByb2R1Y3QgaWRlbnRpZmllci4KICAgICAgICBuYW1lOgogICAgICAgICAgdHlwZTogc3RyaW5nCiAgICAgICAgICBkZXNjcmlwdGlvbjogTmFtZSBvZiB0aGUgcHJvZHVjdC4KICAgICAgICBkZXNjcmlwdGlvbjoKICAgICAgICAgIHR5cGU6IHN0cmluZwogICAgICAgICAgbnVsbGFibGU6IHRydWUKICAgICAgICAgIGRlc2NyaXB0aW9uOiBEZXRhaWxlZCBkZXNjcmlwdGlvbiBvZiB0aGUgcHJvZHVjdC4KICAgICAgICBwcmljZToKICAgICAgICAgIHR5cGU6IG51bWJlcgogICAgICAgICAgZm9ybWF0OiBmbG9hdAogICAgICAgICAgZGVzY3JpcHRpb246IFByaWNlIG9mIHRoZSBwcm9kdWN0LgogICAgICAgIHN0b2NrOgogICAgICAgICAgdHlwZTogaW50ZWdlcgogICAgICAgICAgZm9ybWF0OiBpbnQzMgogICAgICAgICAgZGVzY3JpcHRpb246IEN1cnJlbnQgc3RvY2sgcXVhbnRpdHkuCiAgICAgICAgICBkZWZhdWx0OiAwCiAgICBQcm9kdWN0SW5wdXQ6CiAgICAgIHR5cGU6IG9iamVjdAogICAgICByZXF1aXJlZDoKICAgICAgICAtIG5hbWUKICAgICAgICAtIHByaWNlCiAgICAgIHByb3BlcnRpZXM6CiAgICAgICAgbmFtZToKICAgICAgICAgIHR5cGU6IHN0cmluZwogICAgICAgICAgZGVzY3JpcHRpb246IE5hbWUgb2YgdGhlIHByb2R1Y3QuCiAgICAgICAgZGVzY3JpcHRpb246CiAgICAgICAgICB0eXBlOiBzdHJpbmcKICAgICAgICAgIG51bGxhYmxlOiB0cnVlCiAgICAgICAgICBkZXNjcmlwdGlvbjogRGV0YWlsZWQgZGVzY3JpcHRpb24gb2YgdGhlIHByb2R1Y3QuCiAgICAgICAgcHJpY2U6CiAgICAgICAgICB0eXBlOiBudW1iZXIKICAgICAgICAgIGZvcm1hdDogZmxvYXQKICAgICAgICAgIGRlc2NyaXB0aW9uOiBQcmljZSBvZiB0aGUgcHJvZHVjdC4KICAgICAgICBzdG9jazoKICAgICAgICAgIHR5cGU6IGludGVnZXIKICAgICAgICAgIGZvcm1hdDogaW50MzIKICAgICAgICAgIGRlc2NyaXB0aW9uOiBJbml0aWFsIHN0b2NrIHF1YW50aXR5LgogICAgICAgICAgZGVmYXVsdDogMA=="
}
}
}
]
}
],
"originalId": "apis/Products-API",
"originalUpdateTime": "2025-07-07T05:23:47.982Z"
}
]
}
}
Loading