> ## Documentation Index
> Fetch the complete documentation index at: https://docs.markpdf.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Go

> net/http para convertir documentos desde Go.

# Go

## Archivo local

```go theme={null}
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

const apiURL = "https://api.markpdf.tech"
const apiKey = "TU_API_KEY"

func main() {
	f, _ := os.Open("informe.pdf")
	defer f.Close()

	req, _ := http.NewRequest("POST", apiURL+"/convert/raw?filename=informe.pdf&mode=fast", f)
	req.Header.Set("x-api-key", apiKey)
	req.Header.Set("content-type", "application/pdf")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
```

## URL firmada

```go theme={null}
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	payload := `{"url":"https://bucket.s3.amazonaws.com/informe.pdf?X-Amz-Signature=...","filename":"informe.pdf","mode":"fast"}`

	req, _ := http.NewRequest("POST", "https://api.markpdf.tech/convert/from-url", strings.NewReader(payload))
	req.Header.Set("x-api-key", "TU_API_KEY")
	req.Header.Set("content-type", "application/json")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
```

## Manejo de 202 (auto-async)

Cuando todos los backends están saturados, la API devuelve `202`. Pollea `/jobs/{id}` hasta obtener el resultado:

```go theme={null}
package main

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"time"
)

const apiURL = "https://api.markpdf.tech"
const apiKey = "TU_API_KEY"

type AcceptedJob struct {
	JobID             string `json:"job_id"`
	RetryAfterSeconds int    `json:"retry_after_seconds"`
}

type JobStatus struct {
	Status string `json:"status"`
	Body   string `json:"body"`
	Error  string `json:"error"`
}

func convert(pdfPath string) (string, error) {
	f, err := os.Open(pdfPath)
	if err != nil {
		return "", err
	}
	defer f.Close()

	req, _ := http.NewRequest("POST", apiURL+"/convert/raw?filename="+pdfPath+"&mode=fast", f)
	req.Header.Set("x-api-key", apiKey)
	req.Header.Set("content-type", "application/pdf")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		return "", err
	}
	defer res.Body.Close()

	if res.StatusCode == 200 {
		body, _ := io.ReadAll(res.Body)
		return string(body), nil
	}

	if res.StatusCode == 202 {
		var job AcceptedJob
		json.NewDecoder(res.Body).Decode(&job)
		delay := time.Duration(job.RetryAfterSeconds) * time.Second
		if delay == 0 {
			delay = 5 * time.Second
		}

		for {
			time.Sleep(delay)

			pollReq, _ := http.NewRequest("GET", fmt.Sprintf("%s/jobs/%s", apiURL, job.JobID), nil)
			pollReq.Header.Set("x-api-key", apiKey)
			pollRes, err := http.DefaultClient.Do(pollReq)
			if err != nil {
				return "", err
			}

			var status JobStatus
			json.NewDecoder(pollRes.Body).Decode(&status)
			pollRes.Body.Close()

			switch status.Status {
			case "completed":
				return status.Body, nil
			case "failed":
				return "", fmt.Errorf("job %s failed: %s", job.JobID, status.Error)
			}
		}
	}

	body, _ := io.ReadAll(res.Body)
	return "", fmt.Errorf("HTTP %d: %s", res.StatusCode, body)
}

func main() {
	md, err := convert("informe.pdf")
	if err != nil {
		panic(err)
	}
	fmt.Println(md)
}
```
