---
**📚 Main Documentation:** [Hoko API Documentation (llms.txt)](https://hoko.to/docs/llms.txt)
This is an individual endpoint documentation file. For the complete API reference, see the main documentation above.
---
# (POST) Create links
Create one or more links in a single request. Each link requires a destination URL and collection ID.
**Category:** Links
## Endpoint

POST /api/links

Create one or more links in a single request. This endpoint accepts an array of link objects, allowing you to create multiple links efficiently in one API call.

Each link requires a destination URL and a collection ID. A unique short ID is automatically generated for each link, producing a short URL and QR code URL under https://hoko.to.

You can include rich metadata such as titles, descriptions, images, UTM parameters, and custom external IDs to organize and track your links effectively.

**Endpoint**

```text
POST /api/links
```

## Authentication

Requires authentication with an API key that has the linksWrite scope.

## Request Body

The request body must be an array of link objects. Each object represents one link to create.

You can create up to 10,000 links in a single request. However, the actual maximum may be lower based on your subscription plan limits and available resources.

| Parameter    | Type          | Required | Location | Description                                                                                              |
| ------------ | ------------- | -------- | -------- | -------------------------------------------------------------------------------------------------------- |
| url          | string (URL)  | Yes      | body     | The destination URL that the short link will redirect to. Must be a valid HTTP/HTTPS URL.                |
| collectionId | string (UUID) | Yes      | body     | The ID of the collection (folder) to organize this link. The collection must exist in your workspace.    |
| title        | string        | No       | body     | A descriptive title for the link. Useful for organization and identification.                            |
| description  | string        | No       | body     | Additional description or notes about the link.                                                          |
| image        | string (URL)  | No       | body     | A preview image URL for the link. Must be a valid HTTP/HTTPS URL.                                        |
| utm          | object        | No       | body     | UTM parameters for campaign tracking. Supports source, medium, campaign, term, content, and referral.    |
| expiresAt    | string        | No       | body     | ISO date-time when the link should expire. Requires a plan with link expiration.                         |
| expiredUrl   | string (URL)  | No       | body     | Destination used after expiration. Requires a plan with link expiration.                                 |
| password     | string        | No       | body     | Password required before resolving the destination. Requires a plan with password protection.            |
| cloaked      | boolean       | No       | body     | Render the resolved destination in an iframe instead of redirecting. Requires a plan with link cloaking. |
| ios          | string (URL)  | No       | body     | Destination for iOS visitors. Requires a plan with device targeting.                                     |
| android      | string (URL)  | No       | body     | Destination for Android visitors. Requires a plan with device targeting.                                 |
| geo          | object        | No       | body     | Country-code destination map such as `{ "SA": "https://example.com/sa" }`. Requires geo targeting.      |
| externalId   | string        | No       | body     | A custom external ID for syncing with external systems. Must be unique within your workspace.            |
| tenantId     | string        | No       | body     | A tenant identifier for multi-tenant scenarios. Useful for segmenting links by customer or organization. |
| partnerId    | string (UUID) | No       | body     | The ID of the partner associated with this link. Used for affiliate and partner attribution tracking.    |

> **Warning: Plan Limits**
> The actual maximum number of links you can create per request may be lower than 10,000 based on your subscription plan limits and available resources. The system will enforce both the hard limit (10,000) and your plan-specific limits.

## Status Codes

### 201

Links created successfully.

**Request**

```bash
curl -X POST "https://hoko.to/api/links" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "url": "https://example.com",
      "collectionId": "550e8400-e29b-41d4-a716-446655440000",
      "expiresAt": "2026-12-31T23:59:00Z",
      "expiredUrl": "https://example.com/expired",
      "password": "launch",
      "cloaked": true,
      "ios": "https://example.com/ios",
      "android": "https://example.com/android",
      "geo": {
        "SA": "https://example.com/sa"
      }
    }
  ]'
```

**Request**

```javascript
const response = await fetch('https://hoko.to/api/links', {
	method: 'POST',
	headers: {
		Authorization: 'Bearer <API_KEY>',
		'Content-Type': 'application/json'
	},
	body: JSON.stringify([
		{
			url: 'https://example.com',
			collectionId: '550e8400-e29b-41d4-a716-446655440000',
			expiresAt: '2026-12-31T23:59:00Z',
			expiredUrl: 'https://example.com/expired',
			password: 'launch',
			cloaked: true,
			ios: 'https://example.com/ios',
			android: 'https://example.com/android',
			geo: {
				SA: 'https://example.com/sa'
			}
		}
	])
});
const links = await response.json();
```

**Response**

```json
[
	{
		"id": "550e8400-e29b-41d4-a716-446655440000",
		"url": "https://example.com",
		"shortUrl": "https://hoko.to/abc123",
		"qrCode": "https://hoko.to/qrcode?text=https%3A%2F%2Fhoko.to%2Fabc123%3Fqr%3D1&size=512&errorCorrection=H&foreground=000000&background=FFFFFF&margin=1&format=svg",
		"expiresAt": "2026-12-31T23:59:00Z",
		"expiredUrl": "https://example.com/expired",
		"password": "launch",
		"cloaked": true,
		"ios": "https://example.com/ios",
		"android": "https://example.com/android",
		"geo": {
			"SA": "https://example.com/sa"
		},
		"createdAt": "2024-01-01T00:00:00Z"
	}
]
```

### 400

Invalid request body (missing required fields or invalid values).

**Request**

```bash
curl -X POST "https://hoko.to/api/links" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "url": "invalid-url"
    }
  ]'
```

**Request**

```javascript
const response = await fetch('https://hoko.to/api/links', {
	method: 'POST',
	headers: {
		Authorization: 'Bearer <API_KEY>',
		'Content-Type': 'application/json'
	},
	body: JSON.stringify([
		{
			url: 'invalid-url'
		}
	])
});
```

**Response**

```json
{
	"error": {
		"en": "Invalid request",
		"ar": "طلب غير صالح"
	}
}
```

### 401

Invalid or missing API key.

**Request**

```bash
curl -X POST "https://hoko.to/api/links" \
  -H "Authorization: Bearer invalid_key"
```

**Request**

```javascript
const response = await fetch('https://hoko.to/api/links', {
	method: 'POST',
	headers: {
		Authorization: 'Bearer invalid_key'
	}
});
```

**Response**

```json
{
	"error": {
		"en": "Invalid API key",
		"ar": "مفتاح API غير صالح"
	}
}
```

### 403

API key does not have the required linksWrite scope.

**Request**

```bash
curl -X POST "https://hoko.to/api/links" \
  -H "Authorization: Bearer <API_KEY>"
```

**Request**

```javascript
const response = await fetch('https://hoko.to/api/links', {
	method: 'POST',
	headers: {
		Authorization: 'Bearer <API_KEY>'
	}
});
```

**Response**

```json
{
	"error": {
		"en": "Missing required scopes",
		"ar": "الصلاحيات المطلوبة مفقودة"
	},
	"missingScopes": ["linksWrite"]
}
```

### 429

Rate limit exceeded. Check X-RateLimit-\* headers for details.

**Request**

```bash
curl -X POST "https://hoko.to/api/links" \
  -H "Authorization: Bearer <API_KEY>"
```

**Request**

```javascript
const response = await fetch('https://hoko.to/api/links', {
	method: 'POST',
	headers: {
		Authorization: 'Bearer <API_KEY>'
	}
});
```

**Response**

```json
{
	"error": {
		"en": "Rate limit exceeded",
		"ar": "تم تجاوز حد المعدل"
	},
	"retryAfter": 60
}
```

## Examples

**Request**

```bash
curl -X POST "https://hoko.to/api/links" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "url": "https://example.com",
      "title": "Example Link",
      "description": "An example link",
      "collectionId": "550e8400-e29b-41d4-a716-446655440000",
      "utm": {
        "source": "google",
        "medium": "cpc",
        "campaign": "summer"
      }
    }
  ]'
```

**Request**

```javascript
const response = await fetch('https://hoko.to/api/links', {
	method: 'POST',
	headers: {
		Authorization: 'Bearer <API_KEY>',
		'Content-Type': 'application/json'
	},
	body: JSON.stringify([
		{
			url: 'https://example.com',
			title: 'Example Link',
			description: 'An example link',
			collectionId: '550e8400-e29b-41d4-a716-446655440000',
			utm: {
				source: 'google',
				medium: 'cpc',
				campaign: 'summer'
			}
		}
	])
});
const links = await response.json();
```

**Response**

```json
[
	{
		"id": "550e8400-e29b-41d4-a716-446655440000",
		"url": "https://example.com",
		"shortUrl": "https://hoko.to/abc123",
		"qrCode": "https://hoko.to/qrcode?text=https%3A%2F%2Fhoko.to%2Fabc123%3Fqr%3D1&size=512&errorCorrection=H&foreground=000000&background=FFFFFF&margin=1&format=svg",
		"title": "Example Link",
		"description": "An example link",
		"collectionId": "550e8400-e29b-41d4-a716-446655440000",
		"createdAt": "2024-01-01T00:00:00Z"
	}
]
```

> **Warning: Important Constraints**
> The collectionId must reference an existing collection in your workspace. The externalId must be unique within your workspace if provided. Plan limits may restrict the number of links you can create per request and overall.

---

**Back to main documentation:** [Hoko API Documentation (llms.txt)](https://hoko.to/docs/llms.txt)