# Image Search - Image Submission API
## Overall Call Flow
```
1. Submit image (/v3/api/open/ai-search/image/submit or /v3/api/open/ai-search/image/submit/image-url) (This API)
   ↓
2. Wait 10-20 seconds
   ↓
3. Query processing status (/v3/api/open/ai-search/image/status)
   ↓
4. Get result summary (/v3/api/open/ai-search/image/resultSummary)
   ↓
5. Based on summary data, selectively call detailed list APIs:
    - Product list: /v3/api/open/ai-search/image/product/search
    - Ad list: /v3/api/open/ai-search/image/search4/ad/search
    - Store list: /v3/api/open/ai-search/image/root-path/search
    - TikTok products: /v3/api/open/ai-search/image/tiktok-product/search
    - TikTok shops: /v3/api/open/ai-search/image/tiktok-shop/search
```
## API Overview

The image search feature provides two image submission methods:

1. **Upload Image File**: Directly upload local image files for search
2. **Submit Image URL**: Search using an image URL address

Both methods will vectorize the image and search for similar content in massive ad, product, and store data, returning an image ID for subsequent result queries.

---

## API 1: Upload Image File

### API Information

- **API Name**: Upload Image File for Image Search
- **Request Method**: POST
- **API Address**: `/open-api/v1/upload-file`
- **API Path**: `/v3/api/open/ai-search/image/submit`
- **API Description**: Upload local image files for image search, suitable for scenarios requiring local image uploads
- **Pricing**: Free

**Request Headers:**

- Content-Type: multipart/form-data
- Accept: application/json

### Request Parameters

#### Multipart Form Fields

Send these three fields directly in a `multipart/form-data` body, without a JSON `params` object. When using cURL `-F` or FormData, let the client generate the Content-Type header with its multipart boundary.

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| key | string | Yes | Your API Key. |
| uri | string | Yes | Set to `/v3/api/open/ai-search/image/submit`. |
| image_data | File | Yes | Local image file. Supported formats: jpg, jpeg, png, gif, bmp, webp. Recommended maximum: 10MB and 4096×4096 pixels. |

### Request Examples

#### Using cURL

```bash
curl -X POST "https://www.pipispy.com/open-api/v1/upload-file" \
  -H "Accept: application/json" \
    -F "image_data=@/path/to/image.jpg" \
    -F "key=your_api_key" \
    -F "uri=/v3/api/open/ai-search/image/submit"
```

#### Using Java (Spring RestTemplate)

```java
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.util.Collections;

public class UploadFileExample {

    public static void main(String[] args) {
        String url = "https://www.pipispy.com/open-api/v1/upload-file";

        // Replace with your own image path and API key.
        String imagePath = "/path/to/image.jpg";
        String apiKey = "your_api_key";
        String uriParam = "/v3/api/open/ai-search/image/submit";

        // Create a RestTemplate instance.
        RestTemplate restTemplate = new RestTemplate();

        // Build a multipart/form-data request body.
        FileSystemResource resource = new FileSystemResource(new File(imagePath));
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        body.add("image_data", resource);
        body.add("key", apiKey);
        body.add("uri", uriParam);

        // Set the request headers.
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));

        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);

        // Send a POST request.
        try {
            ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
            System.out.println("Status Code: " + response.getStatusCode());
            System.out.println("Response Body: " + response.getBody());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
```

**Maven Dependency:**
```xml
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.3.30</version>
</dependency>
```

---

## API 2: Submit Image URL

### API Information

- **API Name**: Image Search via Image URL
- **Request Method**: POST
- **API Address**: `/open-api/v1/data`
- **API Path**: `/v3/api/open/ai-search/image/submit/image-url`
- **API Description**: Search via image URL address, suitable for scenarios where images are already online, no file upload needed
- **Pricing**: Free

**Request Headers:**

- Content-Type: application/json
- Accept: application/json

### Request Parameters

#### Request Structure

| Parameter | Type   | Description                 | Example                                          | Required | Default |
| --------- | ------ | --------------------------- | ------------------------------------------------ | -------- | ------- |
| key       | string | User's external API request key | "your_api_key_here"                              | Yes      |         |
| uri       | string | API path                    | "/v3/api/open/ai-search/image/submit/image-url" | Yes      |         |
| params    | object | API input parameters        | See parameter list                               | Yes      |         |

#### Request Body Parameters (params object)

| Parameter | Type   | Required | Description                                                                                                                                                                                                                          |
| --------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| image_url | String | Yes      | Image URL address. Must be a publicly accessible HTTP/HTTPS link. Supported formats: jpg, jpeg, png, gif, bmp, webp. Recommended size: no more than 10MB, dimensions no more than 4096x4096 pixels. The system will download and convert the image to vectors for similarity matching |

### Request Examples

#### Using cURL

```bash
curl -X POST "https://www.pipispy.com/open-api/v1/data" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "key": "your_api_key_here",
    "uri": "/v3/api/open/ai-search/image/submit/image-url",
    "params": {
        "image_url": "https://example.com/path/to/image.jpg"
    }
  }'
```

#### Using Java (Spring RestTemplate)

```java
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

public class AiSearchImageUrlSubmitSpring {

    public static void main(String[] args) {
        String url = "https://www.pipispy.com/open-api/v1/data";
        String apiKey = "your_api_key_here";
        String imageUrl = "https://example.com/path/to/image.jpg";

        RestTemplate restTemplate = new RestTemplate();

        // Set request headers
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("Accept", "application/json");

        // Build request body
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("key", apiKey);
        requestBody.put("uri", "/v3/api/open/ai-search/image/submit/image-url");

        Map<String, String> params = new HashMap<>();
        params.put("image_url", imageUrl);
        requestBody.put("params", params);

        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);

        // Send request
        ResponseEntity<String> response = restTemplate.exchange(
                url,
                HttpMethod.POST,
                requestEntity,
                String.class
        );

        if (response.getStatusCode() == HttpStatus.OK) {
            System.out.println("Response: " + response.getBody());
        } else {
            System.err.println("Request failed: " + response.getStatusCode());
        }
    }
}
```

**Maven Dependency:**
```xml
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.3.30</version>
</dependency>
```

---

## Response Parameters

### Response Body Structure

Both APIs have the same response format. `data` is the image ID string. Pass it as `image_id` in subsequent requests; do not read `data.image_id`.

```json
{
  "code": 200,
  "message": "success",
  "data": "img_1234567890123456",
  "version": "v1",
  "timestamp": null,
  "sign": null,
  "remaining_credits": 9980,
  "consumed_credits": 0,
  "success": true,
  "fail": false
}
```

### Response Field Description

| Field Name      | Type    | Description                                                                                                                                                      |
| --------------- | ------- |------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| code            | Integer | Response status code, 200 indicates success                                                                                                                      |
| message         | String  | Response message                                                                                                                                                 |
| data            | String  | Response data, unique image identifier (image_id), used for subsequent queries of search status and results. Format: starts with "img_" followed by a timestamp. |
| version         | String  | API version                                                                                                                                                      |
| timestamp       | String  | Response timestamp                                                                                                                                               |
| sign            | String  | Response signature                                                                                                                                               |
| remaining_credits | Long    | Current remaining available credits after this request |
| consumed_credits  | Long    | Credits consumed by this request                       |
| success         | Boolean | Whether request succeeded                                                                                                                                        |
| fail            | Boolean | Whether request failed                                                                                                                                           |

## Response Examples

### Success Response

```json
{
  "code": 200,
  "message": "success",
  "data": "img_1737532800123456",
  "version": "v1",
  "timestamp": null,
  "sign": null,
  "remaining_credits": 9980,
  "consumed_credits": 0,
  "success": true,
  "fail": false
}
```

### Error Response Examples

#### Empty File (API 1 only)

```json
{
  "code": 400,
  "message": "File cannot be empty",
  "data": null,
  "version": "v1",
  "timestamp": null,
  "sign": null,
  "remaining_credits": 9980,
  "consumed_credits": 0,
  "success": false,
  "fail": true
}
```

## Error Code Description

| Error Code | Description                                                       |
| ---------- | ----------------------------------------------------------------- |
| 200        | Success                                                           |
| 400        | Request parameter error (empty file, invalid filename, unsupported format, invalid URL, etc.) |
| 401        | Unauthorized (invalid or expired API Key)                         |
| 500        | Internal server error (image upload failed, vectorization failed, etc.) |

## Next Steps

After successful image submission, you can use the returned `image_id` for the following operations:

1. **Query Processing Status**: Call `/v3/api/open/ai-search/image/status` API to query image processing status
2. **Get Search Result Summary**: Call `/v3/api/open/ai-search/image/resultSummary` API to get result statistics
3. **Query Product List**: Call `/v3/api/open/ai-search/image/product/search` API to get similar products
4. **Query Ad List**: Call `/v3/api/open/ai-search/image/search4/ad/search` API to get similar ads
5. **Query Store List**: Call `/v3/api/open/ai-search/image/root-path/search` API to get related stores
6. **Query TikTok Products**: Call `/v3/api/open/ai-search/image/tiktok-product/search` API to get TikTok Shop products
7. **Query TikTok Shops**: Call `/v3/api/open/ai-search/image/tiktok-shop/search` API to get TikTok Shops

## Processing Flow Description

Processing flow after image submission:

1. **Image Acquisition (approx. 1-3 seconds)**:
   - API 1: System saves uploaded image to OSS storage
   - API 2: System downloads image from URL and saves to OSS storage
2. **Vector Extraction (approx. 2-5 seconds)**: Use AI model to extract image feature vectors
3. **Vector Retrieval (approx. 1-3 seconds)**: Search for similar images in Milvus vector database
4. **Result Organization (approx. 2-5 seconds)**: Filter and organize search results

The entire process typically completes within 10-20 seconds. It's recommended to wait a few seconds after submitting the image before calling the status query API.
