# API Documentation

## Bearer Token & API Key Generation

**Bearer authentication** (also called **token authentication**) is an HTTP **authentication** scheme that involves security **tokens** called **bearer tokens**. GoGovSG uses bearer authentication.&#x20;

To generate the token, click on "API Integration" in the navigation bar. From there, click on `Generate API key` and copy the token. Use this key to start using GoGovSG's API.&#x20;

<figure><img src="/files/VADqrzfgHS49QDa2OUnq" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/GxQSJBsdvBzA5WtpBe8f" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
**Keep the bearer token** **safe:** You should not share the bearer token with anyone. Use services like 1Password to store it.&#x20;
{% endhint %}

## Authentication

GoGovSG's API uses APIKey for authentication. User can view and manage API Keys in Go API Dashboard.

Staging secret keys will have `test_v1_`version prefix.

Production secret keys will have `live_v1_`version prefix.

Authentication to the API is performed via bearer auth.

```powershell
curl --location --request POST 'https://go.gov.sg/api/v1/urls' \
--header 'Authorization: Bearer live_v1_YOUR_API_KEY'
```

All API requests must be made over HTTPS. Calls made over plain HTTP will fail and requests without authentication will also fail.

## Errors

Go API uses conventional API Error to indicate the success or failure of an API request.

| Status Codes                       | Description                                                                                      |
| ---------------------------------- | ------------------------------------------------------------------------------------------------ |
| 200 - OK                           | Everything worked as expected.                                                                   |
| 400 - Bad Request                  | The request was unacceptable, often due to missing a required parameter.                         |
| 401 - Unauthorized                 | No valid API key provided.                                                                       |
| 402 - Request Failed               | The parameters were valid but the request failed.                                                |
| 404 - Not Found                    | The requested resource doesn't exist.                                                            |
| 429 - Too Many Requests            | Too many requests hit the API too quickly. We recommend an exponential backoff of your requests. |
| 500, 502, 503, 504 - Server Errors | Something went wrong on GoGovSG's API end.                                                       |

```json
{
  "message": "Unauthorized"
}
```

## Rate Limits

GoGovSG supports a default rate limit of 5 requests per second for each user. If you require higher rate limits, please write to us at <go@open.gov.sg> with more details.

If you have exceeded your rate limit, your incoming requests will be blocked for 10 seconds as a cooling off period. We recommend throttling your requests and implementing exponential backoff for retries to ensure that your requests can be accepted.

## Endpoints

| Environment | Endpoint                                                     |
| ----------- | ------------------------------------------------------------ |
| Production  | [https://go.gov.sg/api/](https://go.gov.sg/)                 |
| Staging     | [https://staging.go.gov.sg/api/](https://staging.go.gov.sg/) |

## Get Urls

```jsx
GET /v1/urls?...
```

**Request Query Parameters:**

<table><thead><tr><th>Parameter</th><th width="201.33333333333331">Type</th><th>Default value</th><th>Required?</th></tr></thead><tbody><tr><td><code>limit</code></td><td>number</td><td>1000</td><td>No, optional</td></tr><tr><td><code>offset</code></td><td>number</td><td>0</td><td>No, optional</td></tr><tr><td><code>searchText</code></td><td>string</td><td>nil</td><td>No, optional</td></tr><tr><td><code>state</code></td><td>enum (”ACTIVE”, “INACTIVE”)</td><td>nil</td><td>No, optional</td></tr><tr><td><code>orderBy</code></td><td>enum (”createdAt”, “clicks”)</td><td>createdAt</td><td>No, optional</td></tr><tr><td><code>sortDirection</code></td><td>enum (”desc”, “asc”)</td><td>desc</td><td>No, optional</td></tr><tr><td><code>isFile</code></td><td>boolean</td><td>nil</td><td>No, optional</td></tr></tbody></table>

Note: Max values for `limit` = 1000

**Returns**:

```json
{
  "urls": [
    {
      "shortUrl": "197abc",
      "longUrl": "https://link.com",
      "state": "ACTIVE",
      "clicks": 0,
      "createdAt": "2022-09-19T03:31:00.131Z",
      "updatedAt": "2022-09-19T03:31:00.131Z"
    }
  ],
  "count": 1
}
```

**Explanation of fields returned:**

<table><thead><tr><th width="173">Field Returned</th><th width="256">What it means</th><th>Example</th></tr></thead><tbody><tr><td><code>shortUrl</code></td><td>Short link name</td><td>agsubmit <br><br>(ie. full URL will look like https://go.gov.sg/agsubmit)</td></tr><tr><td><code>longUrl</code></td><td>Original link</td><td>https://google.com</td></tr><tr><td><code>state</code></td><td>Whether short link is active or inactive</td><td>"ACTIVE" or "INACTIVE"</td></tr><tr><td><code>clicks</code></td><td>Number of clicks on the short link since creation</td><td>888</td></tr><tr><td><code>count</code></td><td>Counts the total number of links matching search filters (except <code>limit</code> and <code>offset</code>) </td><td>8</td></tr></tbody></table>

## Create Url

```jsx
POST /v1/urls
```

**Request body:**

| Property | Type   | Required?     |
| -------- | ------ | ------------- |
| longUrl  | string | Yes, required |
| shortUrl | string | No, optional  |

* &#x20;`longUrl` has to start with https\://
* If no `shortUrl` is provided, then a random 8 character alphanumeric shortUrl name will be generated for the link.

**Returns**:

```json
{
  "shortUrl": "197abc",
  "longUrl": "https://link.com",
  "state": "ACTIVE",
  "clicks": 0,
  "createdAt": "2022-09-19T03:31:00.131Z",
  "updatedAt": "2022-09-19T03:31:00.131Z"
}
```

```json
{
  "message": "Short link \\"asd\\" is already used.",
  "type": "ShortUrlError"
}
```

## Update Url

```jsx
PATCH /v1/urls/{shortUrl}
```

Note: Indicate `shortUrl` name you wish to update in above PATCH request, ie. {shortUrl}

**Request body:**

<table><thead><tr><th>Property</th><th width="278.3333333333333">Type</th><th>Required?</th></tr></thead><tbody><tr><td><code>longUrl</code></td><td>string</td><td>No, optional</td></tr><tr><td><code>state</code></td><td>enum (”ACTIVE”, “INACTIVE”)</td><td>No, optional</td></tr></tbody></table>

* `longUrl` has to start with https\://

**Returns**:

```jsx
{
  "shortUrl": "197abc",
  "longUrl": "https://link.com",
  "state": "ACTIVE",
  "clicks": 0,
  "createdAt": "2022-09-19T03:31:00.131Z",
  "updatedAt": "2022-09-19T03:31:00.131Z"
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://guide.go.gov.sg/developer-guide/api-documentation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
