> Portal Navigation:
> 
> - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version.
> - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages).
> - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`).
> - Top-level index of all portals: https://dev.wix.com/docs/llms.txt
> - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt

# BulkCreateRedirects

# Package: redirects

# Namespace: RedirectsService

# Method link: https://dev.wix.com/docs/api-reference/business-management/seo/redirects/redirect-v1/bulk-create-redirects.md

## Permission Scopes:
Manage SEO Settings: SCOPE.PROMOTE.MANAGE-SEO

## Introduction

Creates up to 500 redirects.

Each redirect succeeds or fails on its own. A redirect whose `from` path is already taken fails
with `FROM_URL_EXISTS`, and one that closes a loop with an earlier redirect in the same request
fails with `REDIRECT_LOOP`, while the rest of the request goes ahead. Read those failures from
`results[].itemMetadata.error` in a successful response, matched to the request by
`results[].itemMetadata.originalIndex`. A malformed request, such as an empty `redirects` list,
is rejected as a whole and returns no results.

A redirect that already exists with the same `from`, `to`, and `options.groupRedirect` is
reported as a success with no `id`, and nothing is written for it.

A redirect that closes a loop with a redirect already on the site is created, and the
loop-closing redirect is deleted. `options.forceReplace` does the same for a `from` path that's
already taken by a redirect on the site, instead of failing that redirect. Neither deletion can
be undone, so retrieve those redirects first if you need to restore them.

To create a single redirect, call [Create Redirect](https://dev.wix.com/docs/api-reference/business-management/seo/redirects/redirect-v1/create-redirect.md).

---

## REST API

### Schema

```
 Method: bulkCreateRedirects
 Description: Creates up to 500 redirects.  Each redirect succeeds or fails on its own. A redirect whose `from` path is already taken fails with `FROM_URL_EXISTS`, and one that closes a loop with an earlier redirect in the same request fails with `REDIRECT_LOOP`, while the rest of the request goes ahead. Read those failures from `results[].itemMetadata.error` in a successful response, matched to the request by `results[].itemMetadata.originalIndex`. A malformed request, such as an empty `redirects` list, is rejected as a whole and returns no results.  A redirect that already exists with the same `from`, `to`, and `options.groupRedirect` is reported as a success with no `id`, and nothing is written for it.  A redirect that closes a loop with a redirect already on the site is created, and the loop-closing redirect is deleted. `options.forceReplace` does the same for a `from` path that's already taken by a redirect on the site, instead of failing that redirect. Neither deletion can be undone, so retrieve those redirects first if you need to restore them.  To create a single redirect, call [Create Redirect](https://dev.wix.com/docs/api-reference/business-management/seo/redirects/redirect-v1/create-redirect.md).
 URL: https://www.wixapis.com/seo-redirects-service/v1/bulk/redirects/create
 Method: POST
 # Note: If the parameter `a.b` is listed under required parameters, `b` is only required if `a` is also present.
 Required parameters:  redirects
 Method parameters: 
   param name: options | type: BulkCreateRedirectsOptions | description: Extra options for creating redirects in bulk.  
        - name: forceReplace | type: boolean | description: Whether to delete a redirect on the site that already starts from the same `from` path and create the new one in its place. When `false`, a redirect whose `from` path is taken fails with `FROM_URL_EXISTS` while the rest of the request goes ahead.  Applies only to redirects already on the site. A redirect that clashes with an earlier redirect in the same request always fails. The replaced redirect is deleted for good, so retrieve it first if you might need to restore it.  Default: `false`  
   param name: redirects | type: array<redirects> | description: Redirects to create. | required: true | validation: minItems 1, maxItems 500
              - name: from | type: string | description: Path on the site that the redirect starts from, URL-encoded. For example, `/old-page`.  Can't be the site root. A path that differs from another redirect's `from` path only by a trailing slash counts as the same path.  For a redirect scoped to a `language`, specify the path with or without the language prefix: the prefix is stripped, so a `fr` redirect from `/fr/about` is stored and returned as `/about`.  | validation: maxLength 950
              - name: to | type: string | description: Where the redirect sends the visitor, URL-encoded. Either a path on the site, such as `/new-page`, or a full URL, such as `https://example.com/page`.  | validation: maxLength 4096
              - name: options | type: RedirectOptions | description: How the redirect matches the paths a visitor requests.  
                 - name: groupRedirect | type: boolean | description: Whether the redirect matches every path under its `from` path, carrying the rest of the URL over to the target. For example, a group redirect from `/forum/questions/` to `/forum/faqs/` sends `/forum/questions/my-post` to `/forum/faqs/my-post`. When `false`, only the exact `from` path matches.  A group redirect and an exact redirect that share a `from` path are two different redirects.  Default: `false`  
              - name: language | type: string | description: Language version of a multilingual site that the redirect applies to, as a 2-letter language code or a language tag. For example, `fr` or `en-US`.  When omitted, the redirect applies to every language on the site. A redirect scoped to a language conflicts only with redirects in the same language and with redirects that apply to every language.  Deleting a redirect scoped to a language stops it taking effect, but it can still appear in [List Redirects](https://dev.wix.com/docs/api-reference/business-management/seo/redirects/redirect-v1/list-redirects.md).  | validation: minLength 2, maxLength 5
              - name: id | type: string | description: Redirect GUID.  You can specify your own GUID when creating a redirect. When omitted, an GUID is generated.  | validation: format GUID
   param name: returnFullEntity | type: returnFullEntity | description: Whether to return the created redirects in `results[].item`, and not only their metadata.  Default: `false`  
 Return type: BulkCreateRedirectsResponse
  - name: results | type: array<BulkRedirectResult> | description: Outcome of each redirect, in request order.  | validation: maxItems 500
     - name: itemMetadata | type: ItemMetadata | description: Whether this redirect succeeded, its position in the request as `originalIndex`, and the error if it failed.  A redirect that already exists on the site is reported as a success with no `id`, and nothing is written for it.  
        - name: id | type: string | description: Item GUID. Should always be available, unless it's impossible (for example, when failing to create an item).  | validation: maxLength 100
        - name: originalIndex | type: integer | description: Index of the item within the request array. Allows for correlation between request and response items.  
        - name: success | type: boolean | description: Whether the requested action was successful for this item. When `false`, the `error` field is populated.  
        - name: error | type: ApplicationError | description: Details about the error in case of failure.  
           - name: code | type: string | description: Error code.  
           - name: description | type: string | description: Description of the error.  
           - name: data | type: object | description: Data related to the error.  
     - name: item | type: Redirect | description: Created redirect.  Returned only when `returnFullEntity` is `true` in the request. Never returned by Bulk Delete Redirects.  
        - name: from | type: string | description: Path on the site that the redirect starts from, URL-encoded. For example, `/old-page`.  Can't be the site root. A path that differs from another redirect's `from` path only by a trailing slash counts as the same path.  For a redirect scoped to a `language`, specify the path with or without the language prefix: the prefix is stripped, so a `fr` redirect from `/fr/about` is stored and returned as `/about`.  | validation: maxLength 950
        - name: to | type: string | description: Where the redirect sends the visitor, URL-encoded. Either a path on the site, such as `/new-page`, or a full URL, such as `https://example.com/page`.  | validation: maxLength 4096
        - name: options | type: RedirectOptions | description: How the redirect matches the paths a visitor requests.  
           - name: groupRedirect | type: boolean | description: Whether the redirect matches every path under its `from` path, carrying the rest of the URL over to the target. For example, a group redirect from `/forum/questions/` to `/forum/faqs/` sends `/forum/questions/my-post` to `/forum/faqs/my-post`. When `false`, only the exact `from` path matches.  A group redirect and an exact redirect that share a `from` path are two different redirects.  Default: `false`  
        - name: language | type: string | description: Language version of a multilingual site that the redirect applies to, as a 2-letter language code or a language tag. For example, `fr` or `en-US`.  When omitted, the redirect applies to every language on the site. A redirect scoped to a language conflicts only with redirects in the same language and with redirects that apply to every language.  Deleting a redirect scoped to a language stops it taking effect, but it can still appear in [List Redirects](https://dev.wix.com/docs/api-reference/business-management/seo/redirects/redirect-v1/list-redirects.md).  | validation: minLength 2, maxLength 5
        - name: id | type: string | description: Redirect GUID.  You can specify your own GUID when creating a redirect. When omitted, an GUID is generated.  | validation: format GUID
        - name: createdDate | type: string | description: Date and time the redirect was created.  Not returned by [Create Redirect](https://dev.wix.com/docs/api-reference/business-management/seo/redirects/redirect-v1/create-redirect.md). Call [Get Redirect](https://dev.wix.com/docs/api-reference/business-management/seo/redirects/redirect-v1/get-redirect.md) or [List Redirects](https://dev.wix.com/docs/api-reference/business-management/seo/redirects/redirect-v1/list-redirects.md) to retrieve it.  | read-only: true | validation: format date-time
  - name: bulkActionMetadata | type: BulkActionMetadata | description: Number of redirects created and number that failed.  `undetailedFailures` counts redirects whose outcome is unknown. They may or may not have been created, and they carry no error, so call [List Redirects](https://dev.wix.com/docs/api-reference/business-management/seo/redirects/redirect-v1/list-redirects.md) to check them.  
     - name: totalSuccesses | type: integer | description: Number of items that were successfully processed.  
     - name: totalFailures | type: integer | description: Number of items that couldn't be processed.  
     - name: undetailedFailures | type: integer | description: Number of failures without details because detailed failure threshold was exceeded.  

 Possible Errors:
   HTTP Code: 400 | Status Code: INVALID_ARGUMENT | Application Code:  | Description: The `redirects` list is missing or empty, or a redirect in it is missing `from` or `to`. Nothing is written and the response carries no per-item results.


```

### Examples

### Create several redirects, with one entry failing
Per-entry failures arrive inside a 200 response. Correlate them to the request with `itemMetadata.originalIndex`, not with the HTTP status. Here the third entry claims a `from` path the first entry already took. Set `returnFullEntity` to `true` to get the created redirects back in `results[].item`.

```curl
curl -X POST \
'https://www.wixapis.com/seo-redirects-service/v1/bulk/redirects/create' \
-H 'Authorization: <AUTH>' \
-H 'Content-Type: application/json' \
-d '{
  "redirects": [
    { "from": "/old-pricing", "to": "/pricing" },
    { "from": "/old-contact", "to": "/contact" },
    { "from": "/old-pricing", "to": "/plans" }
  ],
  "returnFullEntity": true
}'
```

---

## JavaScript SDK

### Schema

```
 Method: wixClientAdmin.seo.redirects.bulkCreateRedirects(redirects, options)
 Description: Creates up to 500 redirects.  Each redirect succeeds or fails on its own. A redirect whose `from` path is already taken fails with `FROM_URL_EXISTS`, and one that closes a loop with an earlier redirect in the same request fails with `REDIRECT_LOOP`, while the rest of the request goes ahead. Read those failures from `results[].itemMetadata.error` in a successful response, matched to the request by `results[].itemMetadata.originalIndex`. A malformed request, such as an empty `redirects` list, is rejected as a whole and returns no results.  A redirect that already exists with the same `from`, `to`, and `options.groupRedirect` is reported as a success with no `id`, and nothing is written for it.  A redirect that closes a loop with a redirect already on the site is created, and the loop-closing redirect is deleted. `options.forceReplace` does the same for a `from` path that's already taken by a redirect on the site, instead of failing that redirect. Neither deletion can be undone, so retrieve those redirects first if you need to restore them.  To create a single redirect, call [Create Redirect](https://dev.wix.com/docs/api-reference/business-management/seo/redirects/redirect-v1/create-redirect.md).
 # Note: If the parameter `a.b` is listed under required parameters, `b` is only required if `a` is also present.
 Required parameters:  redirects
 Method parameters: 
   param name: options | type: BulkCreateRedirectsOptions  none  
        - name: returnFullEntity | type: boolean | description: Whether to return the created redirects in `results[].item`, and not only their metadata.  Default: `false`  
        - name: options | type: BulkCreateRedirectsOptions | description: Extra options for creating the redirects.  
           - name: forceReplace | type: boolean | description: Whether to delete a redirect on the site that already starts from the same `from` path and create the new one in its place. When `false`, a redirect whose `from` path is taken fails with `FROM_URL_EXISTS` while the rest of the request goes ahead.  Applies only to redirects already on the site. A redirect that clashes with an earlier redirect in the same request always fails. The replaced redirect is deleted for good, so retrieve it first if you might need to restore it.  Default: `false`  
   param name: redirects | type: array<array> | description: Redirects to create. | required: true | validation: minItems 1, maxItems 500
              - name: from | type: string | description: Path on the site that the redirect starts from, URL-encoded. For example, `/old-page`.  Can't be the site root. A path that differs from another redirect's `from` path only by a trailing slash counts as the same path.  For a redirect scoped to a `language`, specify the path with or without the language prefix: the prefix is stripped, so a `fr` redirect from `/fr/about` is stored and returned as `/about`.  | validation: maxLength 950
              - name: to | type: string | description: Where the redirect sends the visitor, URL-encoded. Either a path on the site, such as `/new-page`, or a full URL, such as `https://example.com/page`.  | validation: maxLength 4096
              - name: options | type: RedirectOptions | description: How the redirect matches the paths a visitor requests.  
                 - name: groupRedirect | type: boolean | description: Whether the redirect matches every path under its `from` path, carrying the rest of the URL over to the target. For example, a group redirect from `/forum/questions/` to `/forum/faqs/` sends `/forum/questions/my-post` to `/forum/faqs/my-post`. When `false`, only the exact `from` path matches.  A group redirect and an exact redirect that share a `from` path are two different redirects.  Default: `false`  
              - name: language | type: string | description: Language version of a multilingual site that the redirect applies to, as a 2-letter language code or a language tag. For example, `fr` or `en-US`.  When omitted, the redirect applies to every language on the site. A redirect scoped to a language conflicts only with redirects in the same language and with redirects that apply to every language.  Deleting a redirect scoped to a language stops it taking effect, but it can still appear in [List Redirects](https://dev.wix.com/docs/api-reference/business-management/seo/redirects/redirect-v1/list-redirects.md).  | validation: minLength 2, maxLength 5
              - name: _id | type: string | description: Redirect GUID.  You can specify your own GUID when creating a redirect. When omitted, an GUID is generated.  | validation: format GUID
 Return type: PROMISE<BulkCreateRedirectsResponse>
  - name: results | type: array<BulkRedirectResult> | description: Outcome of each redirect, in request order.  | validation: maxItems 500
     - name: itemMetadata | type: ItemMetadata | description: Whether this redirect succeeded, its position in the request as `originalIndex`, and the error if it failed.  A redirect that already exists on the site is reported as a success with no `id`, and nothing is written for it.  
        - name: _id | type: string | description: Item GUID. Should always be available, unless it's impossible (for example, when failing to create an item).  | validation: maxLength 100
        - name: originalIndex | type: integer | description: Index of the item within the request array. Allows for correlation between request and response items.  
        - name: success | type: boolean | description: Whether the requested action was successful for this item. When `false`, the `error` field is populated.  
        - name: error | type: ApplicationError | description: Details about the error in case of failure.  
           - name: code | type: string | description: Error code.  
           - name: description | type: string | description: Description of the error.  
           - name: data | type: object | description: Data related to the error.  
     - name: item | type: Redirect | description: Created redirect.  Returned only when `returnFullEntity` is `true` in the request. Never returned by Bulk Delete Redirects.  
        - name: from | type: string | description: Path on the site that the redirect starts from, URL-encoded. For example, `/old-page`.  Can't be the site root. A path that differs from another redirect's `from` path only by a trailing slash counts as the same path.  For a redirect scoped to a `language`, specify the path with or without the language prefix: the prefix is stripped, so a `fr` redirect from `/fr/about` is stored and returned as `/about`.  | validation: maxLength 950
        - name: to | type: string | description: Where the redirect sends the visitor, URL-encoded. Either a path on the site, such as `/new-page`, or a full URL, such as `https://example.com/page`.  | validation: maxLength 4096
        - name: options | type: RedirectOptions | description: How the redirect matches the paths a visitor requests.  
           - name: groupRedirect | type: boolean | description: Whether the redirect matches every path under its `from` path, carrying the rest of the URL over to the target. For example, a group redirect from `/forum/questions/` to `/forum/faqs/` sends `/forum/questions/my-post` to `/forum/faqs/my-post`. When `false`, only the exact `from` path matches.  A group redirect and an exact redirect that share a `from` path are two different redirects.  Default: `false`  
        - name: language | type: string | description: Language version of a multilingual site that the redirect applies to, as a 2-letter language code or a language tag. For example, `fr` or `en-US`.  When omitted, the redirect applies to every language on the site. A redirect scoped to a language conflicts only with redirects in the same language and with redirects that apply to every language.  Deleting a redirect scoped to a language stops it taking effect, but it can still appear in [List Redirects](https://dev.wix.com/docs/api-reference/business-management/seo/redirects/redirect-v1/list-redirects.md).  | validation: minLength 2, maxLength 5
        - name: _id | type: string | description: Redirect GUID.  You can specify your own GUID when creating a redirect. When omitted, an GUID is generated.  | validation: format GUID
        - name: _createdDate | type: Date | description: Date and time the redirect was created.  Not returned by [Create Redirect](https://dev.wix.com/docs/api-reference/business-management/seo/redirects/redirect-v1/create-redirect.md). Call [Get Redirect](https://dev.wix.com/docs/api-reference/business-management/seo/redirects/redirect-v1/get-redirect.md) or [List Redirects](https://dev.wix.com/docs/api-reference/business-management/seo/redirects/redirect-v1/list-redirects.md) to retrieve it.  | read-only: true 
  - name: bulkActionMetadata | type: BulkActionMetadata | description: Number of redirects created and number that failed.  `undetailedFailures` counts redirects whose outcome is unknown. They may or may not have been created, and they carry no error, so call [List Redirects](https://dev.wix.com/docs/api-reference/business-management/seo/redirects/redirect-v1/list-redirects.md) to check them.  
     - name: totalSuccesses | type: integer | description: Number of items that were successfully processed.  
     - name: totalFailures | type: integer | description: Number of items that couldn't be processed.  
     - name: undetailedFailures | type: integer | description: Number of failures without details because detailed failure threshold was exceeded.  

 Possible Errors:
   HTTP Code: 400 | Status Code: INVALID_ARGUMENT | Application Code:  | Description: The `redirects` list is missing or empty, or a redirect in it is missing `from` or `to`. Nothing is written and the response carries no per-item results.


```

### Examples

### Create several redirects, with one entry failing
Per-entry failures resolve successfully. Correlate them to the request with `itemMetadata.originalIndex`. Here the third entry claims a `from` path the first entry already took.

```javascript
import { redirects } from "@wix/seo";

async function bulkCreateRedirects() {
  const response = await redirects.bulkCreateRedirects(
    [
      { from: "/old-pricing", to: "/pricing" },
      { from: "/old-contact", to: "/contact" },
      { from: "/old-pricing", to: "/plans" },
    ],
    { returnFullEntity: true },
  );
}

/* Promise resolves to:
 * {
 *   "results": [
 *     {
 *       "itemMetadata": {
 *         "originalIndex": 0,
 *         "success": true,
 *         "_id": "fa19f816-440b-4414-b6c7-828fb13e1639"
 *       },
 *       "item": {
 *         "from": "/old-pricing",
 *         "to": "/pricing",
 *         "options": {
 *           "groupRedirect": false
 *         },
 *         "_id": "fa19f816-440b-4414-b6c7-828fb13e1639",
 *         "_createdDate": "2026-08-20T07:48:39.879Z"
 *       }
 *     },
 *     {
 *       "itemMetadata": {
 *         "originalIndex": 2,
 *         "success": false,
 *         "error": {
 *           "code": "FROM_URL_EXISTS",
 *           "description": "an earlier redirect in this request already claims /old-pricing"
 *         }
 *       }
 *     }
 *   ],
 *   "bulkActionMetadata": {
 *     "totalSuccesses": 2,
 *     "totalFailures": 1,
 *     "undetailedFailures": 0
 *   }
 * }
 */

```

### bulkCreateRedirects (self-hosted)
Self-hosted SDK calls require you to [create a client](https://dev.wix.com/docs/sdk/articles/work-with-the-sdk/about-the-wix-client.md).

```javascript
import { createClient } from '@wix/sdk';
import { redirects } from '@wix/seo';
// Import the auth strategy for the relevant access type
// Import the relevant host module if needed

const myWixClient = createClient ({
  modules: { redirects },
  // Include the auth strategy and host as relevant
});


async function bulkCreateRedirects(redirects,options) {
  const response = await myWixClient.redirects.bulkCreateRedirects(redirects,options);
};
```

---