> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.pinnacle.sh/v-2/api-reference/tools/create-url/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.pinnacle.sh/_mcp/server. # Create Shortened URL POST https://api.pinnacle.sh/tools/url Content-Type: application/json Create a shortened URL that redirects visitors to the provided destination URL. Reference: https://docs.pinnacle.sh/api-reference/tools/create-url ## Authentication - `PINNACLE-API-KEY` header (required) — API Key authentication via header ## Request ### Body (application/json) This endpoint expects an urlSchema. - `url` (string, required) — Destination URL for the shortened link that visitors will be redirected to when clicked. - `options` (urlOptionsSchema, optional) ## Response ### 200 Successfully created. - `url` (string, required) — Your custom shortened link following the format `https://pncl.to/{linkId}`, where `{linkId}` is the unique identifier for the URL that can be used with our other endpoint. - `config` (PinnacleUrlConfig, required) ## Errors ### 400 Bad Request Error The request was unacceptable, often due to providing an invalid update. Errors may originate from invalid payload or from Pinnacle's additional validation checks. For example, providing an URL that cannot be accessed, updating a campaign that is currently being reviewed, updating data that you cannot access, sending a malformed message, and so on. For `Pinnacle Validation Error` inspect the `error` payload to determine the source of the failure. These errors are likely due to additional validation and business logic checks. For `Request Validation Error` inspect the `description` and `errors` payload to determine the source of failure. These errors are likely due to invalid payload inside the request. - `CreateShortenedUrlRequestBadRequestError` ### 401 Unauthorized Error The request lacks valid authentication credentials or the provided credentials are invalid. Ensure you're including a valid API key in the request headers and that your account has the necessary permissions to access this endpoint. - `error` (string, required) — Human-readable description of the error that occurred, corresponding to the HTTP status code. ### 403 Forbidden Error Your subscription does not include access to this feature. This occurs when attempting to use functionality that requires a higher subscription tier. Please upgrade your subscription to access this feature. - `error` (string, required) — Human-readable description of the error that occurred, corresponding to the HTTP status code. ### 500 Internal Server Error An unexpected error occurred on Pinnacle's servers while processing your request. If this error persists, please contact support with the request details. - `error` (string, required) — Human-readable description of the error that occurred, corresponding to the HTTP status code. ## Types ### urlOptionsSchema - `expiresAt` (string, optional, nullable) — Expiration date in ISO 8601 format for the shortened URL. If omitted, then a permalink is generated instead. Short permalinks contain a 30-digit link id. Short links with an expiration date contain a 8-digit link id. ### PinnacleUrlConfig - `to` (string, required) — Destination URL that your shortened link redirects to. - `expiresAt` (string, required, nullable) — Expiration date for your shortened link in ISO 8601 format, or null if it's permanent. ### ZodError - `description` (string, required) — Human-readable summary of validation failures. - `errors` (ZodErrorErrors, required) — Structured dictionary of issues containing two main sections: - `errors`: Array of global validation errors not tied to specific fields - `properties`: Object mapping field names to their specific validation errors, where each field contains an `errors` array ### Error Standard error response returned when a request cannot be processed successfully. - `error` (string, required) — Human-readable description of the error that occurred, corresponding to the HTTP status code. ### ZodErrorErrors Structured dictionary of issues containing two main sections: - `errors`: Array of global validation errors not tied to specific fields - `properties`: Object mapping field names to their specific validation errors, where each field contains an `errors` array ## Examples **Request** ```json { "url": "https://www.pinnacle.sh/", "options": { "expiresAt": "2025-06-23T16:18:25.000Z" } } ``` **Response** ```json { "url": "https://pncl.to/hJCJadm9", "config": { "to": "https://docs.pinnacle.sh/", "expiresAt": "2025-06-23T16:18:25+00:00" } } ``` **SDK Code** ```python Shortened URL import requests url = "https://api.pinnacle.sh/tools/url" payload = { "url": "https://www.pinnacle.sh/", "options": { "expiresAt": "2025-06-23T16:18:25.000Z" } } headers = { "PINNACLE-API-KEY": "", "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```javascript Shortened URL const url = 'https://api.pinnacle.sh/tools/url'; const options = { method: 'POST', headers: {'PINNACLE-API-KEY': '', 'Content-Type': 'application/json'}, body: '{"url":"https://www.pinnacle.sh/","options":{"expiresAt":"2025-06-23T16:18:25.000Z"}}' }; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go Shortened URL package main import ( "fmt" "strings" "net/http" "io" ) func main() { url := "https://api.pinnacle.sh/tools/url" payload := strings.NewReader("{\n \"url\": \"https://www.pinnacle.sh/\",\n \"options\": {\n \"expiresAt\": \"2025-06-23T16:18:25.000Z\"\n }\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("PINNACLE-API-KEY", "") req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```ruby Shortened URL require 'uri' require 'net/http' url = URI("https://api.pinnacle.sh/tools/url") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Post.new(url) request["PINNACLE-API-KEY"] = '' request["Content-Type"] = 'application/json' request.body = "{\n \"url\": \"https://www.pinnacle.sh/\",\n \"options\": {\n \"expiresAt\": \"2025-06-23T16:18:25.000Z\"\n }\n}" response = http.request(request) puts response.read_body ``` ```java Shortened URL import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("https://api.pinnacle.sh/tools/url") .header("PINNACLE-API-KEY", "") .header("Content-Type", "application/json") .body("{\n \"url\": \"https://www.pinnacle.sh/\",\n \"options\": {\n \"expiresAt\": \"2025-06-23T16:18:25.000Z\"\n }\n}") .asString(); ``` ```php Shortened URL request('POST', 'https://api.pinnacle.sh/tools/url', [ 'body' => '{ "url": "https://www.pinnacle.sh/", "options": { "expiresAt": "2025-06-23T16:18:25.000Z" } }', 'headers' => [ 'Content-Type' => 'application/json', 'PINNACLE-API-KEY' => '', ], ]); echo $response->getBody(); ``` ```csharp Shortened URL using RestSharp; var client = new RestClient("https://api.pinnacle.sh/tools/url"); var request = new RestRequest(Method.POST); request.AddHeader("PINNACLE-API-KEY", ""); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\n \"url\": \"https://www.pinnacle.sh/\",\n \"options\": {\n \"expiresAt\": \"2025-06-23T16:18:25.000Z\"\n }\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); ``` ```swift Shortened URL import Foundation let headers = [ "PINNACLE-API-KEY": "", "Content-Type": "application/json" ] let parameters = [ "url": "https://www.pinnacle.sh/", "options": ["expiresAt": "2025-06-23T16:18:25.000Z"] ] as [String : Any] let postData = JSONSerialization.data(withJSONObject: parameters, options: []) let request = NSMutableURLRequest(url: NSURL(string: "https://api.pinnacle.sh/tools/url")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "POST" request.allHTTPHeaderFields = headers request.httpBody = postData as Data let session = URLSession.shared let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in if (error != nil) { print(error as Any) } else { let httpResponse = response as? HTTPURLResponse print(httpResponse) } }) dataTask.resume() ``` > One API for RCS, iMessage, MMS, and SMS. Build, test, and scale every channel — send your first message in minutes, not weeks.