Skip to main content
Glama

Update qURL

update_qurl

Update a qURL resource's expiration ceiling, tags, description, custom domain, or proxy host-header behavior. extend_by/expires_at here move the resource's own expiry, which does not keep an individual link open longer; use…

Instructions

Update a qURL resource's expiration ceiling, tags, description, custom domain, or proxy host-header behavior. extend_by/expires_at here move the resource's own expiry, which does not keep an individual link open longer; use extend_qurl or update_qurl_token to change a link's expiry. Accepts resource public keys, CRIDs, legacy r_ IDs, and q_ display IDs for expiration, tags, and description updates (q_ is auto-resolved); custom domain and preserve_host updates require a resource identifier (public key, CRID, or legacy r_ ID) because the qURL API now serves them from PATCH /v1/resources/{id}. Constraints: extend_by and expires_at are mutually exclusive; custom_domain/preserve_host cannot be combined with expiration changes in one call; at least one update field (extend_by, expires_at, tags, description, custom_domain, preserve_host) must be set. Clearing fields: pass description: "", tags: [], or custom_domain: "" to clear those fields explicitly. Use delete_qurl when you want to revoke entirely. Errors: a malformed or out-of-range extend_by is rejected by input validation; if the input fails schema refinements (both extend_by + expires_at, or no fields set), the handler returns an isError: true content block. Both happen before any API call. Other API errors throw with the API's code/statusCode. Returns the updated resource (same shape as get_qurl).

Input Schema

NameRequiredDescriptionDefault
tagsNoReplace all tags on this resource (max 10 tags, each 1-50 chars)
extend_byNoDuration to extend by (e.g., "24h", "7d"; 1m to 30d per call; use expires_at for longer). Mutually exclusive with expires_at.
expires_atNoAbsolute expiration timestamp (RFC 3339). Mutually exclusive with extend_by.
descriptionNoReplace the resource description (max 500 chars)
resource_idYesThe resource public key, CRID, legacy r_ ID, or qURL display ID (q_ prefix) to update. If a q_ ID is passed, the API resolves it to the parent resource automatically.
custom_domainNoReplace the custom domain bound to this resource (max 253 chars, must be registered/active/owned). Pass "" to clear.
preserve_hostNoWhether to preserve the original Host header when proxying via the custom domain. Only meaningful when custom_domain is set; default false on the API side.

Output Schema

NameRequiredDescriptionDefault
cridNo
slugNoImmutable per-owner resource identity, when one was supplied at create time
tagsNo
qurlsNo
statusYesunknown
privateNo
qurl_siteNo
created_atYes
expires_atYes
qurl_countNoNumber of access tokens minted for this resource
target_urlNoUnderlying URL the qURL protects; omitted on connector-owned resources
descriptionNo
resource_idYesStable resource identifier (public key or legacy r_ ID)
custom_domainNo
preserve_hostNoWhen true, the original Host header is preserved when proxying via the custom domain. Only meaningful when custom_domain is set; defaults to false on the API side.
consumer_accessNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changedv0.2.2
    • changedInput schema / properties / extend_by / description
      Previous value: -"Duration to extend by (e.g., \"24h\", \"7d\"). Mutually exclusive with expires_at."New value: +"Duration to extend by (e.g., \"24h\", \"7d\"; 1m to 30d per call; use expires_at for longer). Mutually exclusive with expires_at."
    • addedInput schema / properties / extend_by / maxLength
      Added value: +32
    • removedInput schema / properties / extend_by / minLength
      Removed value: -1
    • addedOutput schema / properties / consumer_access
      Added value: +{
      +  "additionalProperties": false,
      +  "properties": {
      +    "contract_id": {
      +      "type": "string"
      +    },
      +    "mode": {
      +      "type": "string"
      +    },
      +    "version": {
      +      "type": "number"
      +    }
      +  },
      +  "required": [
      +    "mode"
      +  ],
      +  "type": "object"
      +}
    • addedOutput schema / properties / crid
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / private
      Added value: +{
      +  "type": "boolean"
      +}
  2. Changed8 schema fields changedv0.2.1
    • removedInput schema / additionalProperties
      Removed value: -false
    • addedInput schema / properties / custom_domain
      Added value: +{
      +  "description": "Replace the custom domain bound to this resource (max 253 chars, must be registered/active/owned). Pass \"\" to clear.",
      +  "maxLength": 253,
      +  "type": "string"
      +}
    • addedInput schema / properties / expires_at / pattern
      Added value: +"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
    • addedInput schema / properties / preserve_host
      Added value: +{
      +  "description": "Whether to preserve the original Host header when proxying via the custom domain. Only meaningful when custom_domain is set; default false on the API side.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / resource_id / description
      Previous value: -"The resource ID (r_ prefix) or qURL display ID (q_ prefix) to update. If a q_ ID is passed, the API resolves it to the parent resource automatically."New value: +"The resource public key, CRID, legacy r_ ID, or qURL display ID (q_ prefix) to update. If a q_ ID is passed, the API resolves it to the parent resource automatically."
    • removedInput schema / properties / resource_id / minLength
      Removed value: -1
    • addedInput schema / properties / resource_id / pattern
      Added value: +"(?:^(r_[a-z0-9_-]{11}|(?:[A-Za-z0-9_-]{4}){27,53}|(?:[A-Za-z0-9_-]{4}){27,53}[A-Za-z0-9_-]{2}|(?:[A-Za-z0-9_-]{4}){26,52}[A-Za-z0-9_-]{3}|[a-z2-7]{47}|[a-z2-7]{60})$)|(?:^q_[0-9a-f]{11}$)"
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": {},
      +  "properties": {
      +    "created_at": {
      +      "type": "string"
      +    },
      +    "custom_domain": {
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "description": {
      +      "type": "string"
      +    },
      +    "expires_at": {
      +      "type": "string"
      +    },
      +    "preserve_host": {
      +      "description": "When true, the original Host header is preserved when proxying via the custom domain. Only meaningful when custom_domain is set; defaults to false on the API side.",
      +      "type": "boolean"
      +    },
      +    "qurl_count": {
      +      "description": "Number of access tokens minted for this resource",
      +      "type": "number"
      +    },
      +    "qurl_site": {
      +      "type": "string"
      +    },
      +    "qurls": {
      +      "items": {
      +        "additionalProperties": {},
      +        "description": "Single access token belonging to a qURL resource",
      +        "properties": {
      +          "access_policy": {
      +            "additionalProperties": {},
      +            "description": "Access control policy snapshot for this token",
      +            "properties": {
      +              "ai_agent_policy": {
      +                "additionalProperties": {},
      +                "properties": {
      +                  "allow_categories": {
      +                    "items": {
      +                      "type": "string"
      +                    },
      +                    "type": "array"
      +                  },
      +                  "block_all": {
      +                    "type": "boolean"
      +                  },
      +                  "deny_categories": {
      +                    "items": {
      +                      "type": "string"
      +                    },
      +                    "type": "array"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              "geo_allowlist": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "geo_denylist": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "ip_allowlist": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "ip_denylist": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "user_agent_allow_regex": {
      +                "type": "string"
      +              },
      +              "user_agent_deny_regex": {
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "created_at": {
      +            "type": "string"
      +          },
      +          "expires_at": {
      +            "type": "string"
      +          },
      +          "label": {
      +            "type": "string"
      +          },
      +          "max_sessions": {
      +            "type": "number"
      +          },
      +          "one_time_use": {
      +            "type": "boolean"
      +          },
      +          "qurl_id": {
      +            "type": "string"
      +          },
      +          "qurl_site": {
      +            "type": "string"
      +          },
      +          "session_duration": {
      +            "description": "Seconds of access granted after a successful resolve",
      +            "type": "number"
      +          },
      +          "status": {
      +            "default": "unknown",
      +            "description": "Per-token status (wider than resource status — tokens may be consumed/expired independently)",
      +            "enum": [
      +              "active",
      +              "consumed",
      +              "expired",
      +              "revoked",
      +              "unknown"
      +            ],
      +            "type": "string"
      +          },
      +          "use_count": {
      +            "type": "number"
      +          }
      +        },
      +        "required": [
      +          "qurl_id",
      +          "status"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "resource_id": {
      +      "description": "Stable resource identifier (public key or legacy r_ ID)",
      +      "type": "string"
      +    },
      +    "slug": {
      +      "description": "Immutable per-owner resource identity, when one was supplied at create time",
      +      "type": "string"
      +    },
      +    "status": {
      +      "default": "unknown",
      +      "enum": [
      +        "active",
      +        "revoked",
      +        "expired",
      +        "unknown"
      +      ],
      +      "type": "string"
      +    },
      +    "tags": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "target_url": {
      +      "description": "Underlying URL the qURL protects; omitted on connector-owned resources",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "resource_id",
      +    "expires_at",
      +    "created_at",
      +    "status"
      +  ],
      +  "type": "object"
      +}
  3. First observedv0.2.0

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare non-read-only, non-destructive, non-idempotent, open-world behavior, and the description adds substantial context beyond them: explicit field-clearing semantics ("", []), which identifier types are accepted per field and why (PATCH /v1/resources/{id} for domain/preserve_host), and precise error behavior including the isError content block returned before any API call for schema refinement failures.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and alternatives, then constraints, clearing, and errors in labeled bold sections. It is dense but every section is actionable; minor redundancy exists where the mutual-exclusivity and at-least-one-field rules are stated both in the constraints block and echoed in the errors paragraph.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter mutation tool with full schema coverage, an output schema, and non-trivial annotation coverage, the description covers routing, constraints, clearing, identifier requirements, and failure modes, and points to get_qurl for the return shape. Nothing material is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3, but the description goes further by explaining clearing behavior for description/tags/custom_domain and the identifier-type restrictions for custom domain and preserve_host (q_ IDs not accepted there). It largely restates the extend_by/expires_at mutual exclusion already present in the schema, so it is not a full 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource ("Update a qURL resource") and enumerates the mutable fields (expiration ceiling, tags, description, custom domain, proxy host-header behavior), immediately distinguishing it from siblings like extend_qurl and update_qurl_token, which it names.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit routing guidance is provided: use extend_qurl or update_qurl_token to change an individual link's expiry, and use delete_qurl to revoke entirely. It also states the constraint conditions (at least one field required, mutual exclusivity, no combining domain changes with expiration changes) that determine when the tool can be used at all.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.