# GET2POST — GET-to-HTTP proxy for AI agents Send HTTP requests from GET-only AI tools. Supply a destination, method, body, and headers in a GET URL; the server sends the selected HTTP request and returns the response. Use it for requests your user has authorized. This service does not expand your permissions to access a destination or perform an action. Base URL: https://www.postviaget.com Alternative base URL: https://get2post.vercel.app (also works) Public source: https://github.com/tylerthecoder/get-to-post Endpoint: GET /api/post Reading /, /llms.txt, or /builder does not send an upstream request. Calling /api/post can. ## Logging Every converter API call is logged to a private Neon database, including rejected requests. Logs include the time, method, destination, request body, query parameters, incoming and upstream request headers, response status, duration, and byte counts. Incoming headers may include your IP address and user agent. Upstream response bodies are not stored. Static pages, assets, and builder navigation are not part of this API log. The database is private and under my control. I, Tyler Tracy, will read the logs roughly every two weeks. I won't share them widely, but I may share logs with people at my own discretion if I think doing so will benefit humanity. There is no automatic deletion period. There is no public log viewer or log-reading API. The application is configured with an insert-only database role. Access still depends on database credentials, account permissions, and any tools or people I authorize. Neon and Vercel process request data to operate the service, subject to their own access controls. Request URLs contain your body and headers and may also appear in Vercel logs, client history, or shared links. Redaction in the Neon log does not remove those other copies. The destination receives the original request body and explicit upstream headers. Inspect the logging/redaction implementation in lib/request-log.js and database permissions in db/001-request-logs.sql and scripts/setup-db.mjs in the public repo. Source code documents the implementation; it cannot prove deployed permissions, exclusive access, or my sharing decisions. Access and sharing promises are the operator's commitments. Common credential fields (Authorization, Cookie, API keys, passwords, secrets, tokens, and signatures) are redacted in headers and structured query/body fields. Referer and Vercel internal headers are also redacted. Malformed JSON bodies and text/XML are retained with best-effort redaction: recognizable credential assignments have their value and remaining text redacted. Invalid structured headers and URLs are omitted; oversized requests/headers and deeply nested content are bounded. Redaction cannot identify all secrets, especially in nested URLs, encoded JSON strings, free text, or unusual field names. Do not send confidential data. Requests must be recorded before an upstream request can be sent. If logging is unavailable, the API returns 503 logging_unavailable and sends no upstream request. If recording the outcome fails after sending, the original request remains logged and the actual upstream result is returned with X-Request-Log-Status: request-only. Do not retry an action just to get a complete log. An interrupted request may have no outcome. Requests blocked before reaching the function cannot be logged in this database. ## Quick start curl --get 'https://www.postviaget.com/api/post' \ --data-urlencode 'url=https://httpbin.org/post' \ --data-urlencode 'data={"message":"Hello from an AI agent"}' \ --data-urlencode 'headers={"Content-Type":"application/json"}' \ --data-urlencode 'response=json' If your tool accepts only a URL, URL-encode each query value and request: https://www.postviaget.com/api/post?url=https%3A%2F%2Fhttpbin.org%2Fpost&data=%7B%22message%22%3A%22Hello%22%7D&response=json To use another method, add method=PATCH (or PUT, DELETE, GET, HEAD, OPTIONS, TRACE, CONNECT, or an extension method) to the query parameters. The incoming request remains GET. Omitting method preserves POST behavior. For example: https://www.postviaget.com/api/post?url=https%3A%2F%2Fhttpbin.org%2Fanything&method=PATCH&data=%7B%22message%22%3A%22Updated%22%7D&response=json ## Link-only builder Start at https://www.postviaget.com/builder if you can fetch pages and follow links but cannot enter text or submit forms. Every edit is a normal hyperlink; no JavaScript, cookies, or session is required. Follow Edit destination, then use the URL fragments, letters, uppercase letters, numbers, symbols, JSON fragments, and header fragments shown together on every editing page. Done saves a draft; Cancel editing restores the saved field. Use Backspace, Clear field, and Start over as needed. Edit body and headers independently; JSON fragments and Header fragments reduce typing. Only Unicode character opens a separate page: enter a hexadecimal code point and append the resulting character, then use Back to all tokens to return. Headers remain JSON text while editing; review validates the completed object. Edit method offers standard method presets and custom token editing. Old builder links default to POST. Change response mode selects json or raw. Edit timeout offers presets and digit links. Review request shows the complete draft without sending anything. Only the distinct Execute request link on a valid review page calls /api/post. Do not follow it without authorization. Retries or scanners can repeat an action. Destination DNS checks still run at execution, not while browsing the builder. Each link carries the full state as base64url JSON. Encoding is not encryption: body and header values are visible on the page and may appear in URL logs, client history, and copied links. Do not enter secrets or confidential data. Navigation is not written to the Neon request-log database; execution uses the logging policy above. No server credentials are inserted into builder state. Builder URLs and final API URLs each have a 12 KiB limit. Saved values plus an editing draft add overhead, so some requests that fit the direct API may not fit the builder. Unavailable links are marked; shorten fields or use the API. ## Parameters - url (required): Absolute public HTTPS destination, port 443 only. No URL credentials or fragment. Destination query strings are allowed. - method (default POST): HTTP method token, normalized to uppercase. GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE, CONNECT, and custom tokens such as PROPFIND are accepted. Empty or malformed tokens return 400 invalid_method. HEAD returns an empty body. TRACE and CONNECT require empty data. CONNECT requires an HTTPS origin without a path or query; it targets that same host on port 443 and returns handshake status/headers with an empty body, then closes the connection. No tunnel is relayed. Use response=json to read headers. - data (default empty): Exact UTF-8 request body. JSON, form data, XML, or text. - headers (default {}): JSON object with up to 32 string values. Content-Type defaults to application/json. For form data use application/x-www-form-urlencoded. - response (default raw): Prefer json for agents. It returns HTTP 200 with {status, headers, encoding, body} when an upstream response is available. Inspect result.status for upstream success. JSON bodies are parsed; binary or compressed bodies use base64. Set-Cookie is omitted. raw preserves the upstream status and body bytes with safe content types, not arbitrary response headers. - timeout (default 15000): Upstream deadline, integer 1–20000 milliseconds. Database logging can add up to 6 seconds outside this upstream deadline. Use URLSearchParams or curl --data-urlencode. Do not concatenate unescaped JSON into a URL. Duplicate and unknown parameters are rejected. ## Responses and errors JSON envelope: {"status":200,"headers":{"content-type":"application/json"},"encoding":"utf8","body":{"ok":true}} Converter error: {"error":{"code":"invalid_url","message":"..."}} 400 invalid input or detected prefetch; 401 optional converter key missing/wrong; 403 blocked destination; 405 unsupported incoming method; 414 URL too long; 502 upstream connection/TLS/DNS failure or response too large; 503 logging unavailable (no upstream request sent); 504 timeout (request may have been processed). X-Upstream-Status identifies upstream responses. X-Upstream-Content-Type contains the original media type. Compressed raw bytes are identified by X-Upstream-Content-Encoding. X-Request-Id identifies the private log record; X-Request-Log-Status is complete, request-only, or unavailable. ## Constraints - Every GET can have upstream side effects. Retries, scanners, or reopening URLs can repeat an action. Use an upstream idempotency key when available. A timeout does not undo a request. Redirects are never followed, and no Location header is forwarded in raw mode; inspect Location in the JSON envelope if needed. - Incoming HEAD, OPTIONS, and known prefetches send no upstream request. Use GET with method=HEAD or method=OPTIONS to send those methods upstream. Responses use no-store. - Only public HTTPS endpoints. Private/special-use IPs and mixed private/public DNS answers are blocked; connections use a vetted IP with TLS verification. - Host, Content-Length, Accept-Encoding, hop-by-hop, proxy, X-Forwarded-*, and X-Vercel-* request headers cannot be overridden. Caller credentials/cookies are never forwarded automatically; only explicit upstream headers are sent. - Limits: 12 KiB encoded URL, 1 MiB upstream response, no binary uploads/streaming. Clients or Vercel may impose smaller URL limits. Public, best-effort service; no application-level rate limit or availability guarantee. CORS is enabled. - If the owner enables PROXY_API_KEY, send Authorization: Bearer on the incoming GET. Do not put that key in the URL or upstream headers parameter.