Install
openclaw skills install @psyb0t/go-exaTyped Go client for the Exa API providing web search, page contents, similar pages, and cited answers via HTTPS requests.
openclaw skills install @psyb0t/go-exaUnofficial, typed Go client for the Exa search API, in package exa at the module root.
For install, every operation, request options and response fields, see references/setup.md.
x-api-key header. Read it from the EXA_API_KEY environment variable. Never hardcode, commit or log it, and never print a request with its headers.https://api.exa.ai. Search queries, URLs and answer prompts you send leave the machine for Exa, so do not put secrets or private data in them.CostDollars. Research tasks run long and cost more, so start them only when the user asked.github.com/psyb0t/go-exa.AGENTS.md in the repo.import (
"context"
"fmt"
"net/http"
"os"
exa "github.com/psyb0t/go-exa"
)
auth := exa.WithRequestEditorFn(
func(_ context.Context, req *http.Request) error {
req.Header.Set("x-api-key", os.Getenv("EXA_API_KEY"))
return nil
},
)
client, err := exa.NewClientWithResponses("https://api.exa.ai", auth)
if err != nil {
return err
}
numResults := 5
search, err := client.SearchWithResponse(ctx, exa.SearchJSONRequestBody{
Query: "open source vector databases",
NumResults: &numResults,
IncludeDomains: &[]string{"github.com"},
})
if err != nil {
return err // transport failure
}
if search.JSON200 == nil {
return fmt.Errorf("search: %s", search.Status())
}
if search.JSON200.Results != nil {
for _, result := range *search.JSON200.Results {
fmt.Println(*result.Url)
}
}
answer, err := client.AnswerWithResponse(ctx, exa.AnswerJSONRequestBody{
Query: "What is the boiling point of water at sea level?",
})
if err != nil {
return err
}
if answer.JSON200 != nil && answer.JSON200.Answer != nil {
text, err := answer.JSON200.Answer.AsAnswerResponseAnswer0() // string
if err == nil {
fmt.Println(text)
}
}
Most response fields are pointers; check for nil before dereferencing. The error return covers only transport and decoding failures. An API error comes back with JSON200 nil: check StatusCode() and Body.
Response wrappers that share a name with a schema get a 2 suffix: SearchWithResponse returns *exa.SearchResponse2, whose JSON200 is the *exa.SearchResponse schema.