When evolving APIs, prioritize backward compatibility and avoid changing the semantics of existing fields. Instead of overloading existing fields with new meanings, introduce new fields to maintain compatibility with existing usage patterns.

Key principles:

Example from the codebase:

// Instead of changing semantics of existing credentialName field:
if strings.HasSuffix(name, SdsCaSuffix) {
    // This changes behavior for existing users
}

// Better approach - add a new field:
type TLSOptions struct {
    CredentialName       string  // Keep existing semantics
    CaCertCredentialName string  // New field for CA certificates
}

When updating to new API versions, ensure field type changes (like *string to string) are handled correctly and check for both nil pointers and empty strings as appropriate. Always verify that changes follow the official API specification rather than making assumptions about field behavior.