1# Anthropic Go API Library
2
3<a href="https://pkg.go.dev/github.com/anthropics/anthropic-sdk-go"><img src="https://pkg.go.dev/badge/github.com/anthropics/anthropic-sdk-go.svg" alt="Go Reference"></a>
4
5The Anthropic Go library provides convenient access to the [Anthropic REST API](https://docs.anthropic.com/claude/reference/)
6from applications written in Go.
7
8## Installation
9
10<!-- x-release-please-start-version -->
11
12```go
13import (
14 "github.com/anthropics/anthropic-sdk-go" // imported as anthropic
15)
16```
17
18<!-- x-release-please-end -->
19
20Or to pin the version:
21
22<!-- x-release-please-start-version -->
23
24```sh
25go get -u 'github.com/anthropics/anthropic-sdk-go@v1.4.0'
26```
27
28<!-- x-release-please-end -->
29
30## Requirements
31
32This library requires Go 1.18+.
33
34## Usage
35
36The full API of this library can be found in [api.md](api.md).
37
38```go
39package main
40
41import (
42 "context"
43 "fmt"
44
45 "github.com/anthropics/anthropic-sdk-go"
46 "github.com/anthropics/anthropic-sdk-go/option"
47)
48
49func main() {
50 client := anthropic.NewClient(
51 option.WithAPIKey("my-anthropic-api-key"), // defaults to os.LookupEnv("ANTHROPIC_API_KEY")
52 )
53 message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
54 MaxTokens: 1024,
55 Messages: []anthropic.MessageParam{{
56 Content: []anthropic.ContentBlockParamUnion{{
57 OfRequestTextBlock: &anthropic.TextBlockParam{Text: "What is a quaternion?"},
58 }},
59 Role: anthropic.MessageParamRoleUser,
60 }},
61 Model: anthropic.ModelClaude3_7SonnetLatest,
62 })
63 if err != nil {
64 panic(err.Error())
65 }
66 fmt.Printf("%+v\n", message.Content)
67}
68
69```
70
71<details>
72<summary>Conversations</summary>
73
74```go
75messages := []anthropic.MessageParam{
76 anthropic.NewUserMessage(anthropic.NewTextBlock("What is my first name?")),
77}
78
79message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
80 Model: anthropic.ModelClaude3_7SonnetLatest,
81 Messages: messages,
82 MaxTokens: 1024,
83})
84if err != nil {
85 panic(err)
86}
87
88fmt.Printf("%+v\n", message.Content)
89
90messages = append(messages, message.ToParam())
91messages = append(messages, anthropic.NewUserMessage(
92 anthropic.NewTextBlock("My full name is John Doe"),
93))
94
95message, err = client.Messages.New(context.TODO(), anthropic.MessageNewParams{
96 Model: anthropic.ModelClaude3_7SonnetLatest,
97 Messages: messages,
98 MaxTokens: 1024,
99})
100
101fmt.Printf("%+v\n", message.Content)
102```
103
104</details>
105
106<details>
107<summary>System prompts</summary>
108
109```go
110message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
111 Model: anthropic.ModelClaude3_7SonnetLatest,
112 MaxTokens: 1024,
113 System: []anthropic.TextBlockParam{
114 {Text: "Be very serious at all times."},
115 },
116 Messages: messages,
117})
118```
119
120</details>
121
122<details>
123<summary>Streaming</summary>
124
125```go
126content := "What is a quaternion?"
127
128stream := client.Messages.NewStreaming(context.TODO(), anthropic.MessageNewParams{
129 Model: anthropic.ModelClaude3_7SonnetLatest,
130 MaxTokens: 1024,
131 Messages: []anthropic.MessageParam{
132 anthropic.NewUserMessage(anthropic.NewTextBlock(content)),
133 },
134})
135
136message := anthropic.Message{}
137for stream.Next() {
138 event := stream.Current()
139 err := message.Accumulate(event)
140 if err != nil {
141 panic(err)
142 }
143
144 switch eventVariant := event.AsAny().(type) {
145 case anthropic.ContentBlockDeltaEvent:
146 switch deltaVariant := eventVariant.Delta.AsAny().(type) {
147 case anthropic.TextDelta:
148 print(deltaVariant.Text)
149 }
150
151 }
152}
153
154if stream.Err() != nil {
155 panic(stream.Err())
156}
157```
158
159</details>
160
161<details>
162<summary>Tool calling</summary>
163
164```go
165package main
166
167import (
168 "context"
169 "encoding/json"
170 "fmt"
171
172 "github.com/anthropics/anthropic-sdk-go"
173 "github.com/invopop/jsonschema"
174)
175
176func main() {
177 client := anthropic.NewClient()
178
179 content := "Where is San Francisco?"
180
181 println("[user]: " + content)
182
183 messages := []anthropic.MessageParam{
184 anthropic.NewUserMessage(anthropic.NewTextBlock(content)),
185 }
186
187 toolParams := []anthropic.ToolParam{
188 {
189 Name: "get_coordinates",
190 Description: anthropic.String("Accepts a place as an address, then returns the latitude and longitude coordinates."),
191 InputSchema: GetCoordinatesInputSchema,
192 },
193 }
194 tools := make([]anthropic.ToolUnionParam, len(toolParams))
195 for i, toolParam := range toolParams {
196 tools[i] = anthropic.ToolUnionParam{OfTool: &toolParam}
197 }
198
199 for {
200 message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
201 Model: anthropic.ModelClaude3_7SonnetLatest,
202 MaxTokens: 1024,
203 Messages: messages,
204 Tools: tools,
205 })
206
207 if err != nil {
208 panic(err)
209 }
210
211 print(color("[assistant]: "))
212 for _, block := range message.Content {
213 switch block := block.AsAny().(type) {
214 case anthropic.TextBlock:
215 println(block.Text)
216 println()
217 case anthropic.ToolUseBlock:
218 inputJSON, _ := json.Marshal(block.Input)
219 println(block.Name + ": " + string(inputJSON))
220 println()
221 }
222 }
223
224 messages = append(messages, message.ToParam())
225 toolResults := []anthropic.ContentBlockParamUnion{}
226
227 for _, block := range message.Content {
228 switch variant := block.AsAny().(type) {
229 case anthropic.ToolUseBlock:
230 print(color("[user (" + block.Name + ")]: "))
231
232 var response interface{}
233 switch block.Name {
234 case "get_coordinates":
235 var input struct {
236 Location string `json:"location"`
237 }
238
239 err := json.Unmarshal([]byte(variant.JSON.Input.Raw()), &input)
240 if err != nil {
241 panic(err)
242 }
243
244 response = GetCoordinates(input.Location)
245 }
246
247 b, err := json.Marshal(response)
248 if err != nil {
249 panic(err)
250 }
251
252 println(string(b))
253
254 toolResults = append(toolResults, anthropic.NewToolResultBlock(block.ID, string(b), false))
255 }
256
257 }
258 if len(toolResults) == 0 {
259 break
260 }
261 messages = append(messages, anthropic.NewUserMessage(toolResults...))
262 }
263}
264
265type GetCoordinatesInput struct {
266 Location string `json:"location" jsonschema_description:"The location to look up."`
267}
268
269var GetCoordinatesInputSchema = GenerateSchema[GetCoordinatesInput]()
270
271type GetCoordinateResponse struct {
272 Long float64 `json:"long"`
273 Lat float64 `json:"lat"`
274}
275
276func GetCoordinates(location string) GetCoordinateResponse {
277 return GetCoordinateResponse{
278 Long: -122.4194,
279 Lat: 37.7749,
280 }
281}
282
283func GenerateSchema[T any]() anthropic.ToolInputSchemaParam {
284 reflector := jsonschema.Reflector{
285 AllowAdditionalProperties: false,
286 DoNotReference: true,
287 }
288 var v T
289
290 schema := reflector.Reflect(v)
291
292 return anthropic.ToolInputSchemaParam{
293 Properties: schema.Properties,
294 }
295}
296
297func color(s string) string {
298 return fmt.Sprintf("\033[1;%sm%s\033[0m", "33", s)
299}
300```
301
302</details>
303
304### Request fields
305
306The anthropic library uses the [`omitzero`](https://tip.golang.org/doc/go1.24#encodingjsonpkgencodingjson)
307semantics from the Go 1.24+ `encoding/json` release for request fields.
308
309Required primitive fields (`int64`, `string`, etc.) feature the tag <code>\`json:"...,required"\`</code>. These
310fields are always serialized, even their zero values.
311
312Optional primitive types are wrapped in a `param.Opt[T]`. These fields can be set with the provided constructors, `anthropic.String(string)`, `anthropic.Int(int64)`, etc.
313
314Any `param.Opt[T]`, map, slice, struct or string enum uses the
315tag <code>\`json:"...,omitzero"\`</code>. Its zero value is considered omitted.
316
317The `param.IsOmitted(any)` function can confirm the presence of any `omitzero` field.
318
319```go
320p := anthropic.ExampleParams{
321 ID: "id_xxx", // required property
322 Name: anthropic.String("..."), // optional property
323
324 Point: anthropic.Point{
325 X: 0, // required field will serialize as 0
326 Y: anthropic.Int(1), // optional field will serialize as 1
327 // ... omitted non-required fields will not be serialized
328 },
329
330 Origin: anthropic.Origin{}, // the zero value of [Origin] is considered omitted
331}
332```
333
334To send `null` instead of a `param.Opt[T]`, use `param.Null[T]()`.
335To send `null` instead of a struct `T`, use `param.NullStruct[T]()`.
336
337```go
338p.Name = param.Null[string]() // 'null' instead of string
339p.Point = param.NullStruct[Point]() // 'null' instead of struct
340
341param.IsNull(p.Name) // true
342param.IsNull(p.Point) // true
343```
344
345Request structs contain a `.SetExtraFields(map[string]any)` method which can send non-conforming
346fields in the request body. Extra fields overwrite any struct fields with a matching
347key.
348
349> [!WARNING]
350> For security reasons, only use `SetExtraFields` with trusted data.
351
352To send a custom value instead of a struct, use `param.Override[T](value)`.
353
354```go
355// In cases where the API specifies a given type,
356// but you want to send something else, use [SetExtraFields]:
357p.SetExtraFields(map[string]any{
358 "x": 0.01, // send "x" as a float instead of int
359})
360
361// Send a number instead of an object
362custom := param.Override[anthropic.FooParams](12)
363```
364
365### Request unions
366
367Unions are represented as a struct with fields prefixed by "Of" for each of it's variants,
368only one field can be non-zero. The non-zero field will be serialized.
369
370Sub-properties of the union can be accessed via methods on the union struct.
371These methods return a mutable pointer to the underlying data, if present.
372
373```go
374// Only one field can be non-zero, use param.IsOmitted() to check if a field is set
375type AnimalUnionParam struct {
376 OfCat *Cat `json:",omitzero,inline`
377 OfDog *Dog `json:",omitzero,inline`
378}
379
380animal := AnimalUnionParam{
381 OfCat: &Cat{
382 Name: "Whiskers",
383 Owner: PersonParam{
384 Address: AddressParam{Street: "3333 Coyote Hill Rd", Zip: 0},
385 },
386 },
387}
388
389// Mutating a field
390if address := animal.GetOwner().GetAddress(); address != nil {
391 address.ZipCode = 94304
392}
393```
394
395### Response objects
396
397All fields in response structs are ordinary value types (not pointers or wrappers).
398Response structs also include a special `JSON` field containing metadata about
399each property.
400
401```go
402type Animal struct {
403 Name string `json:"name,nullable"`
404 Owners int `json:"owners"`
405 Age int `json:"age"`
406 JSON struct {
407 Name respjson.Field
408 Owner respjson.Field
409 Age respjson.Field
410 ExtraFields map[string]respjson.Field
411 } `json:"-"`
412}
413```
414
415To handle optional data, use the `.Valid()` method on the JSON field.
416`.Valid()` returns true if a field is not `null`, not present, or couldn't be marshaled.
417
418If `.Valid()` is false, the corresponding field will simply be its zero value.
419
420```go
421raw := `{"owners": 1, "name": null}`
422
423var res Animal
424json.Unmarshal([]byte(raw), &res)
425
426// Accessing regular fields
427
428res.Owners // 1
429res.Name // ""
430res.Age // 0
431
432// Optional field checks
433
434res.JSON.Owners.Valid() // true
435res.JSON.Name.Valid() // false
436res.JSON.Age.Valid() // false
437
438// Raw JSON values
439
440res.JSON.Owners.Raw() // "1"
441res.JSON.Name.Raw() == "null" // true
442res.JSON.Name.Raw() == respjson.Null // true
443res.JSON.Age.Raw() == "" // true
444res.JSON.Age.Raw() == respjson.Omitted // true
445```
446
447These `.JSON` structs also include an `ExtraFields` map containing
448any properties in the json response that were not specified
449in the struct. This can be useful for API features not yet
450present in the SDK.
451
452```go
453body := res.JSON.ExtraFields["my_unexpected_field"].Raw()
454```
455
456### Response Unions
457
458In responses, unions are represented by a flattened struct containing all possible fields from each of the
459object variants.
460To convert it to a variant use the `.AsFooVariant()` method or the `.AsAny()` method if present.
461
462If a response value union contains primitive values, primitive fields will be alongside
463the properties but prefixed with `Of` and feature the tag `json:"...,inline"`.
464
465```go
466type AnimalUnion struct {
467 // From variants [Dog], [Cat]
468 Owner Person `json:"owner"`
469 // From variant [Dog]
470 DogBreed string `json:"dog_breed"`
471 // From variant [Cat]
472 CatBreed string `json:"cat_breed"`
473 // ...
474
475 JSON struct {
476 Owner respjson.Field
477 // ...
478 } `json:"-"`
479}
480
481// If animal variant
482if animal.Owner.Address.ZipCode == "" {
483 panic("missing zip code")
484}
485
486// Switch on the variant
487switch variant := animal.AsAny().(type) {
488case Dog:
489case Cat:
490default:
491 panic("unexpected type")
492}
493```
494
495### RequestOptions
496
497This library uses the functional options pattern. Functions defined in the
498`option` package return a `RequestOption`, which is a closure that mutates a
499`RequestConfig`. These options can be supplied to the client or at individual
500requests. For example:
501
502```go
503client := anthropic.NewClient(
504 // Adds a header to every request made by the client
505 option.WithHeader("X-Some-Header", "custom_header_info"),
506)
507
508client.Messages.New(context.TODO(), ...,
509 // Override the header
510 option.WithHeader("X-Some-Header", "some_other_custom_header_info"),
511 // Add an undocumented field to the request body, using sjson syntax
512 option.WithJSONSet("some.json.path", map[string]string{"my": "object"}),
513)
514```
515
516See the [full list of request options](https://pkg.go.dev/github.com/anthropics/anthropic-sdk-go/option).
517
518### Pagination
519
520This library provides some conveniences for working with paginated list endpoints.
521
522You can use `.ListAutoPaging()` methods to iterate through items across all pages:
523
524```go
525iter := client.Beta.Messages.Batches.ListAutoPaging(context.TODO(), anthropic.BetaMessageBatchListParams{
526 Limit: anthropic.Int(20),
527})
528// Automatically fetches more pages as needed.
529for iter.Next() {
530 betaMessageBatch := iter.Current()
531 fmt.Printf("%+v\n", betaMessageBatch)
532}
533if err := iter.Err(); err != nil {
534 panic(err.Error())
535}
536```
537
538Or you can use simple `.List()` methods to fetch a single page and receive a standard response object
539with additional helper methods like `.GetNextPage()`, e.g.:
540
541```go
542page, err := client.Beta.Messages.Batches.List(context.TODO(), anthropic.BetaMessageBatchListParams{
543 Limit: anthropic.Int(20),
544})
545for page != nil {
546 for _, batch := range page.Data {
547 fmt.Printf("%+v\n", batch)
548 }
549 page, err = page.GetNextPage()
550}
551if err != nil {
552 panic(err.Error())
553}
554```
555
556### Errors
557
558When the API returns a non-success status code, we return an error with type
559`*anthropic.Error`. This contains the `StatusCode`, `*http.Request`, and
560`*http.Response` values of the request, as well as the JSON of the error body
561(much like other response objects in the SDK).
562
563To handle errors, we recommend that you use the `errors.As` pattern:
564
565```go
566_, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
567 MaxTokens: 1024,
568 Messages: []anthropic.MessageParam{{
569 Content: []anthropic.ContentBlockParamUnion{{
570 OfText: &anthropic.TextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.NewCacheControlEphemeralParam(), Citations: []anthropic.TextCitationParamUnion{{
571 OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0},
572 }}},
573 }},
574 Role: anthropic.MessageParamRoleUser,
575 }},
576 Model: anthropic.ModelClaude3_7SonnetLatest,
577})
578if err != nil {
579 var apierr *anthropic.Error
580 if errors.As(err, &apierr) {
581 println(string(apierr.DumpRequest(true))) // Prints the serialized HTTP request
582 println(string(apierr.DumpResponse(true))) // Prints the serialized HTTP response
583 }
584 panic(err.Error()) // GET "/v1/messages": 400 Bad Request { ... }
585}
586```
587
588When other errors occur, they are returned unwrapped; for example,
589if HTTP transport fails, you might receive `*url.Error` wrapping `*net.OpError`.
590
591### Timeouts
592
593Requests do not time out by default; use context to configure a timeout for a request lifecycle.
594
595Note that if a request is [retried](#retries), the context timeout does not start over.
596To set a per-retry timeout, use `option.WithRequestTimeout()`.
597
598```go
599// This sets the timeout for the request, including all the retries.
600ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
601defer cancel()
602client.Messages.New(
603 ctx,
604 anthropic.MessageNewParams{
605 MaxTokens: 1024,
606 Messages: []anthropic.MessageParam{{
607 Content: []anthropic.ContentBlockParamUnion{{
608 OfRequestTextBlock: &anthropic.TextBlockParam{Text: "What is a quaternion?"},
609 }},
610 Role: anthropic.MessageParamRoleUser,
611 }},
612 Model: anthropic.ModelClaude3_7SonnetLatest,
613 },
614 // This sets the per-retry timeout
615 option.WithRequestTimeout(20*time.Second),
616)
617```
618
619### Long Requests
620
621> [!IMPORTANT]
622> We highly encourage you use the streaming Messages API for longer running requests.
623
624We do not recommend setting a large `MaxTokens` value without using streaming as some networks may drop idle connections after a certain period of time, which
625can cause the request to fail or [timeout](#timeouts) without receiving a response from Anthropic.
626
627This SDK will also return an error if a non-streaming request is expected to be above roughly 10 minutes long.
628Calling `.Messages.NewStreaming()` or [setting a custom timeout](#timeouts) disables this error.
629
630### File uploads
631
632Request parameters that correspond to file uploads in multipart requests are typed as
633`io.Reader`. The contents of the `io.Reader` will by default be sent as a multipart form
634part with the file name of "anonymous_file" and content-type of "application/octet-stream", so we
635recommend always specifyig a custom content-type with the `anthropic.File(reader io.Reader, filename string, contentType string)`
636helper we provide to easily wrap any `io.Reader` with the appropriate file name and content type.
637
638```go
639// A file from the file system
640file, err := os.Open("/path/to/file.json")
641anthropic.BetaFileUploadParams{
642 File: anthropic.File(file, "custom-name.json", "application/json"),
643 Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaFilesAPI2025_04_14},
644}
645
646// A file from a string
647anthropic.BetaFileUploadParams{
648 File: anthropic.File(strings.NewReader("my file contents"), "custom-name.json", "application/json"),
649 Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaFilesAPI2025_04_14},
650}
651```
652
653The file name and content-type can also be customized by implementing `Name() string` or `ContentType()
654string` on the run-time type of `io.Reader`. Note that `os.File` implements `Name() string`, so a
655file returned by `os.Open` will be sent with the file name on disk.
656
657### Retries
658
659Certain errors will be automatically retried 2 times by default, with a short exponential backoff.
660We retry by default all connection errors, 408 Request Timeout, 409 Conflict, 429 Rate Limit,
661and >=500 Internal errors.
662
663You can use the `WithMaxRetries` option to configure or disable this:
664
665```go
666// Configure the default for all requests:
667client := anthropic.NewClient(
668 option.WithMaxRetries(0), // default is 2
669)
670
671// Override per-request:
672client.Messages.New(
673 context.TODO(),
674 anthropic.MessageNewParams{
675 MaxTokens: 1024,
676 Messages: []anthropic.MessageParam{{
677 Content: []anthropic.ContentBlockParamUnion{{
678 OfRequestTextBlock: &anthropic.TextBlockParam{Text: "What is a quaternion?"},
679 }},
680 Role: anthropic.MessageParamRoleUser,
681 }},
682 Model: anthropic.ModelClaude3_7SonnetLatest,
683 },
684 option.WithMaxRetries(5),
685)
686```
687
688### Accessing raw response data (e.g. response headers)
689
690You can access the raw HTTP response data by using the `option.WithResponseInto()` request option. This is useful when
691you need to examine response headers, status codes, or other details.
692
693```go
694// Create a variable to store the HTTP response
695var response *http.Response
696message, err := client.Messages.New(
697 context.TODO(),
698 anthropic.MessageNewParams{
699 MaxTokens: 1024,
700 Messages: []anthropic.MessageParam{{
701 Content: []anthropic.ContentBlockParamUnion{{
702 OfText: &anthropic.TextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.NewCacheControlEphemeralParam(), Citations: []anthropic.TextCitationParamUnion{{
703 OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0},
704 }}},
705 }},
706 Role: anthropic.MessageParamRoleUser,
707 }},
708 Model: anthropic.ModelClaude3_7SonnetLatest,
709 },
710 option.WithResponseInto(&response),
711)
712if err != nil {
713 // handle error
714}
715fmt.Printf("%+v\n", message)
716
717fmt.Printf("Status Code: %d\n", response.StatusCode)
718fmt.Printf("Headers: %+#v\n", response.Header)
719```
720
721### Making custom/undocumented requests
722
723This library is typed for convenient access to the documented API. If you need to access undocumented
724endpoints, params, or response properties, the library can still be used.
725
726#### Undocumented endpoints
727
728To make requests to undocumented endpoints, you can use `client.Get`, `client.Post`, and other HTTP verbs.
729`RequestOptions` on the client, such as retries, will be respected when making these requests.
730
731```go
732var (
733 // params can be an io.Reader, a []byte, an encoding/json serializable object,
734 // or a "β¦Params" struct defined in this library.
735 params map[string]any
736
737 // result can be an []byte, *http.Response, a encoding/json deserializable object,
738 // or a model defined in this library.
739 result *http.Response
740)
741err := client.Post(context.Background(), "/unspecified", params, &result)
742if err != nil {
743 β¦
744}
745```
746
747#### Undocumented request params
748
749To make requests using undocumented parameters, you may use either the `option.WithQuerySet()`
750or the `option.WithJSONSet()` methods.
751
752```go
753params := FooNewParams{
754 ID: "id_xxxx",
755 Data: FooNewParamsData{
756 FirstName: anthropic.String("John"),
757 },
758}
759client.Foo.New(context.Background(), params, option.WithJSONSet("data.last_name", "Doe"))
760```
761
762#### Undocumented response properties
763
764To access undocumented response properties, you may either access the raw JSON of the response as a string
765with `result.JSON.RawJSON()`, or get the raw JSON of a particular field on the result with
766`result.JSON.Foo.Raw()`.
767
768Any fields that are not present on the response struct will be saved and can be accessed by `result.JSON.ExtraFields()` which returns the extra fields as a `map[string]Field`.
769
770### Middleware
771
772We provide `option.WithMiddleware` which applies the given
773middleware to requests.
774
775```go
776func Logger(req *http.Request, next option.MiddlewareNext) (res *http.Response, err error) {
777 // Before the request
778 start := time.Now()
779 LogReq(req)
780
781 // Forward the request to the next handler
782 res, err = next(req)
783
784 // Handle stuff after the request
785 end := time.Now()
786 LogRes(res, err, start - end)
787
788 return res, err
789}
790
791client := anthropic.NewClient(
792 option.WithMiddleware(Logger),
793)
794```
795
796When multiple middlewares are provided as variadic arguments, the middlewares
797are applied left to right. If `option.WithMiddleware` is given
798multiple times, for example first in the client then the method, the
799middleware in the client will run first and the middleware given in the method
800will run next.
801
802You may also replace the default `http.Client` with
803`option.WithHTTPClient(client)`. Only one http client is
804accepted (this overwrites any previous client) and receives requests after any
805middleware has been applied.
806
807## Amazon Bedrock
808
809To use this library with [Amazon Bedrock](https://aws.amazon.com/bedrock/claude/),
810use the bedrock request option `bedrock.WithLoadDefaultConfig(β¦)` which reads the
811[default config](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html).
812
813Importing the `bedrock` library also globally registers a decoder for `application/vnd.amazon.eventstream` for
814streaming.
815
816```go
817package main
818
819import (
820 "github.com/anthropics/anthropic-sdk-go"
821 "github.com/anthropics/anthropic-sdk-go/bedrock"
822)
823
824func main() {
825 client := anthropic.NewClient(
826 bedrock.WithLoadDefaultConfig(context.Background()),
827 )
828}
829```
830
831If you already have an `aws.Config`, you can also use it directly with `bedrock.WithConfig(cfg)`.
832
833Read more about Anthropic and Amazon Bedrock [here](https://docs.anthropic.com/en/api/claude-on-amazon-bedrock).
834
835## Google Vertex AI
836
837To use this library with [Google Vertex AI](https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-claude),
838use the request option `vertex.WithGoogleAuth(β¦)` which reads the
839[Application Default Credentials](https://cloud.google.com/docs/authentication/application-default-credentials).
840
841```go
842package main
843
844import (
845 "context"
846
847 "github.com/anthropics/anthropic-sdk-go"
848 "github.com/anthropics/anthropic-sdk-go/vertex"
849)
850
851func main() {
852 client := anthropic.NewClient(
853 vertex.WithGoogleAuth(context.Background(), "us-central1", "id-xxx"),
854 )
855}
856```
857
858If you already have `*google.Credentials`, you can also use it directly with
859`vertex.WithCredentials(ctx, region, projectId, creds)`.
860
861Read more about Anthropic and Google Vertex [here](https://docs.anthropic.com/en/api/claude-on-vertex-ai).
862
863## Semantic versioning
864
865This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:
866
8671. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_
8682. Changes that we do not expect to impact the vast majority of users in practice.
869
870We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.
871
872We are keen for your feedback; please open an [issue](https://www.github.com/anthropics/anthropic-sdk-go/issues) with questions, bugs, or suggestions.
873
874## Contributing
875
876See [the contributing documentation](./CONTRIBUTING.md).